diff --git a/contributors.md b/contributors.md index 01213f70..471cbd6d 100644 --- a/contributors.md +++ b/contributors.md @@ -25,4 +25,5 @@ * Thomas P [@dragon5689](https://twitter.com/dragon5689) [github](https://github.com/dragon5689) * Yotam Ofek [@yotamofek](https://twitter.com/yotamofek) [github](https://github.com/yotamofek) * Aleksandr Filatov [@greybax](http://twitter.com/greybax), [github](https://github.com/greybax) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) * James Young [@jamsyoung](http://twitter.com/jamsyoung), [github](https://github.com/jamsyoung) diff --git a/readme.md b/readme.md index c4db1da7..d43333e9 100644 --- a/readme.md +++ b/readme.md @@ -30,6 +30,7 @@ * Thomas P [@dragon5689](https://twitter.com/dragon5689) [github](https://github.com/dragon5689) * Yotam Ofek [@yotamofek](https://twitter.com/yotamofek) [github](https://github.com/yotamofek) * Aleksandr Filatov [@greybax](http://twitter.com/greybax), [github](https://github.com/greybax) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) * James Young [@jamsyoung](http://twitter.com/jamsyoung), [github](https://github.com/jamsyoung) @@ -79,6 +80,7 @@ * [jshint](http://jshint.com/) * [jslint](http://jslint.org/) * [eslint](http://eslint.org/) + * [jscs](https://www.npmjs.org/package/jscs) * [Editorconfig](http://editorconfig.org/) ## Get Smart diff --git a/translations/de_DE/readme.md b/translations/de_DE/readme.md index 51932145..f7f695a5 100644 --- a/translations/de_DE/readme.md +++ b/translations/de_DE/readme.md @@ -23,6 +23,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Code sollte grundsätzlich so aussehen, als wäre er von einer einzigen Person geschrieben worden, völlig egal wie viele letztlich daran gearbeitet haben. diff --git a/translations/es_ES/readme.md b/translations/es_ES/readme.md index 6c375051..468551b0 100644 --- a/translations/es_ES/readme.md +++ b/translations/es_ES/readme.md @@ -29,6 +29,7 @@ * Stephan Lindauer [@stephanlindauer](http://twitter.com/stephanlindauer), [github](https://github.com/stephanlindauer) * Thomas P [@dragon5689](https://twitter.com/dragon5689) [github](https://github.com/dragon5689) * Yotam Ofek [@yotamofek](https://twitter.com/yotamofek) [github](https://github.com/yotamofek) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) diff --git a/translations/fr_FR/readme.md b/translations/fr_FR/readme.md index aca4319d..7f5413c4 100644 --- a/translations/fr_FR/readme.md +++ b/translations/fr_FR/readme.md @@ -23,6 +23,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Tout code, peu importe les bases sur lequels il est établi, devrait ressembler au code tapé par une seule personne, peu importe le nombre de personnes ayant contribué. diff --git a/translations/it_IT/readme.md b/translations/it_IT/readme.md index 06a606bb..505f2e69 100644 --- a/translations/it_IT/readme.md +++ b/translations/it_IT/readme.md @@ -29,6 +29,7 @@ * Stephan Lindauer [@stephanlindauer](http://twitter.com/stephanlindauer), [github](https://github.com/stephanlindauer) * Thomas P [@dragon5689](https://twitter.com/dragon5689) [github](https://github.com/dragon5689) * Yotam Ofek [@yotamofek](https://twitter.com/yotamofek) [github](https://github.com/yotamofek) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Tutto il codice, in qualsiasi linguaggio sia, dovrebbe sembrare come scritto da un'unica persona, non importa quante persone vi abbiano contribuito. diff --git a/translations/ja_JP/readme.md b/translations/ja_JP/readme.md index fd9e5abf..a40f4d07 100644 --- a/translations/ja_JP/readme.md +++ b/translations/ja_JP/readme.md @@ -24,6 +24,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## どんなに多くの人が貢献したとしても、どのコードも一人で書いたようにするべきです。 diff --git a/translations/ko_KR/readme.md b/translations/ko_KR/readme.md index 721c8ee6..a3243249 100644 --- a/translations/ko_KR/readme.md +++ b/translations/ko_KR/readme.md @@ -23,6 +23,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## 코드 기반에 있는 모든 코드는 마치 한 사람이 작성한 것처럼 보여야 합니다. 많은 사람이 코드 작성에 참여했더라도 말이죠. diff --git a/translations/pt_BR/readme.md b/translations/pt_BR/readme.md index a6dad9d5..60ebbdbd 100644 --- a/translations/pt_BR/readme.md +++ b/translations/pt_BR/readme.md @@ -23,6 +23,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Todo código em qualquer aplicação deve parecer como se tivesse sido escrito por uma única pessoa, independentemente de quantas pessoas tenham contribuído. diff --git a/translations/ro_RO/readme.md b/translations/ro_RO/readme.md index 98f6cd96..69c36f03 100644 --- a/translations/ro_RO/readme.md +++ b/translations/ro_RO/readme.md @@ -24,6 +24,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Tot codul dintr-o aplicație trebuie să arate ca și cum ar fi fost scris de o singură persoană, indiferent de câți oameni au contribuit la scrierea lui. diff --git a/translations/ru_RU/readme.md b/translations/ru_RU/readme.md index 389fc158..2b6f6625 100644 --- a/translations/ru_RU/readme.md +++ b/translations/ru_RU/readme.md @@ -24,6 +24,7 @@ * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) * Aleksandr Filatov [@greybax] (http://twitter.com/greybax), [github](https://github.com/greybax) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Код в любом проекте должен выглядеть так, будто его писал один человек, неважно как много людей работали над ним. *** diff --git a/translations/sr_SR/readme.md b/translations/sr_SR/readme.md index 7045a924..d2904ead 100644 --- a/translations/sr_SR/readme.md +++ b/translations/sr_SR/readme.md @@ -24,6 +24,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Sav kod u bilo kojoj "bazi koda" trebalo bi da izgleda kao da ga je napisala jedna osoba, bez obzira koliko je ljudi doprinelo njegovom kreiranju. diff --git a/translations/vi_VN/readme.md b/translations/vi_VN/readme.md new file mode 100644 index 00000000..54b4146c --- /dev/null +++ b/translations/vi_VN/readme.md @@ -0,0 +1,1311 @@ +# Nguyên tắc để Viết Javascript Nhất quán + + +## Đây là một tài liệu sống và những ý tưởng để nâng cao chất lượng code xung quanh chúng ta đều được chào mừng. Đóng góp: fork, clone, branch, commit, push, pull request. + +* Rick Waldron [@rwaldron](http://twitter.com/rwaldron), [github](https://github.com/rwldrn) +* Mathias Bynens [@mathias](http://twitter.com/mathias), [github](https://github.com/mathiasbynens) +* Schalk Neethling [@ossreleasefeed](http://twitter.com/ossreleasefeed), [github](https://github.com/ossreleasefeed/) +* Kit Cambridge [@kitcambridge](http://twitter.com/kitcambridge), [github](https://github.com/kitcambridge) +* Raynos [github](https://github.com/Raynos) +* Matias Arriola [@MatiasArriola](https://twitter.com/MatiasArriola), [github](https://github.com/MatiasArriola/) +* John Fischer [@jfroffice](https://twitter.com/jfroffice), [github](https://github.com/jfroffice/) +* Idan Gazit [@idangazit](http://twitter.com/idangazit), [github](https://github.com/idan) +* Leo Balter [@leobalter](http://twitter.com/leobalter), [github](https://github.com/leobalter) +* Breno Oliveira [@garu_rj](http://twitter.com/garu_rj), [github](https://github.com/garu) +* Leo Beto Souza [@leobetosouza](http://twitter.com/leobetosouza), [github](https://github.com/leobetosouza) +* Ryuichi Okumura [@okuryu](http://twitter.com/okuryu), [github](https://github.com/okuryu) +* Pascal Precht [@PascalPrecht](http://twitter.com/PascalPrecht), [github](https://github.com/pascalprecht) +* EngForDev [engfordev](http://www.opentutorials.org/course/167/1363) - Hwan Min Hong / MinTaek Kwon [@leoinsight](http://twitter.com/leoinsight) / Tw Shim [@marocchino](http://twitter.com/marocchino), [github](https://github.com/marocchino) / Nassol Kim [@nassol99](http://twitter.com/nassol99), [github](https://github.com/nassol) / Juntai Park [@rkJun](http://twitter.com/rkJun), [github](https://github.com/rkJun) / Minkyu Shim / Gangmin Won / Justin Yoo [@justinchronicle](http://twitter.com/justinchronicle) / Daeyup Lee +* Marco Trulla [@marcotrulla](http://twitter.com/marcotrulla), [github](https://github.com/Ragnarokkr) +* Alex Navasardyan [@alexnavasardyan](http://twitter.com/alexnavasardyan), [github](https://github.com/2k00l) +* Mihai Paun [@mihaipaun](http://twitter.com/mihaipaun), [github](https://github.com/mihaipaun) +* Evgeny Mandrikov [@\_godin\_](http://twitter.com/_godin_), [github](https://github.com/Godin) +* Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) +* Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) +* Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Firede [@firede](https://twitter.com/firede) [github](https://github.com/firede) +* monkadd [github](https://github.com/monkadd) +* Stephan Lindauer [@stephanlindauer](http://twitter.com/stephanlindauer), [github](https://github.com/stephanlindauer) +* Thomas P [@dragon5689](https://twitter.com/dragon5689) [github](https://github.com/dragon5689) +* Yotam Ofek [@yotamofek](https://twitter.com/yotamofek) [github](https://github.com/yotamofek) +* Aleksandr Filatov [@greybax] (http://twitter.com/greybax), [github](https://github.com/greybax) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) + + + +## Tất cả code trong bộ mã nguồn nên nhìn giống như một người viết ra, cho dù có bao nhiêu người đóng góp. + +### Danh sách dưới đây chỉ ra những thực hành mà tôi dùng trong tất cả các code mà tôi là tác giả ban đầu; những đóng góp tới các dự án mà tôi tạo ra nên đi theo các chỉ dẫn đó. + +### Tôi không định ép người khác phải theo phong cách viết của tôi; nếu có một kiểu viết chung, kiểu viết đó nên được làm theo. + + +> ### "Tranh cãi về phong cách là vô nghĩa. Nên có một hướng dẫn về phong cách, và bạn nên làm theo." +>_Rebecca_ _Murphey_ + + + +> ### "Một phần của người quản lý dự án tốt là nhận ra rằng viết code cho bản thân anh ta là một Ý Tưởng Tồi™. Nếu có hàng ngàn người đang dùng code của bạn, thì bạn nên viết code cho rõ ràng tối đa, chứ không phải theo cách bạn thích rằng thế này là thông minh trong một khuôn khổ." +>_Idan_ _Gazit_ + + +## Bản dịch + +* [German](https://github.com/rwldrn/idiomatic.js/tree/master/translations/de_DE) +* [French](https://github.com/rwldrn/idiomatic.js/tree/master/translations/fr_FR) +* [Spanish](https://github.com/rwldrn/idiomatic.js/tree/master/translations/es_ES) +* [Portuguese - Brazil](https://github.com/rwldrn/idiomatic.js/tree/master/translations/pt_BR) +* [Korean](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ko_KR) +* [Japanese](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ja_JP) +* [Italian](https://github.com/rwldrn/idiomatic.js/tree/master/translations/it_IT) +* [Russian](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ru_RU) +* [Romanian](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ro_RO) +* [简体中文](https://github.com/rwldrn/idiomatic.js/tree/master/translations/zh_CN) +* [Serbian - cyrilic alphabet](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ср_СР) +* [Serbian - latin aplphabet](https://github.com/rwldrn/idiomatic.js/tree/master/translations/sr_SR) +* [Tiếng Việt](https://github.com/rwldrn/idiomatic.js/tree/master/translations/vi_VN) + + +## Quan trọng, những thành phần không nhất quán + +### Công cụ Chất lượng Code, Tài nguyên & Tham khảo + +* [JavaScript Plugin](http://docs.codehaus.org/display/SONAR/JavaScript+Plugin) dành cho [Sonar](http://www.sonarsource.org/) +* [Plato](https://github.com/es-analysis/plato) +* [jsPerf](http://jsperf.com/) +* [jsFiddle](http://jsfiddle.net/) +* [jsbin](http://jsbin.com/) +* [JavaScript Lint (JSL)](http://javascriptlint.com/) +* [jshint](http://jshint.com/) +* [jslint](http://jslint.org/) +* [eslint](http://eslint.org/) +* [jscs](https://www.npmjs.org/package/jscs) + +## Trở nên thông minh + +### [Chú giải ECMAScript 5.1](http://es5.github.com/) +### [Đặc tả kỹ thuật của Ngôn Ngữ EcmaScript, Phiên bản 5.1](http://ecma-international.org/ecma-262/5.1/) + +Những thứ dưới đây nên coi là 1) không đầy đủ, and 2) *YÊU CẦU ĐỌC*. Tôi không phải lúc nào cũng đồng ý với phong cách của những tác giả dưới đây, nhưng có một điều là chắc chắc: Tất cả đều nhất quán. Thêm nữa, đây là những người có ảnh hưởng đến ngôn ngữ. + +* [Baseline For Front End Developers](http://rmurphey.com/blog/2012/04/12/a-baseline-for-front-end-developers/) +* [Eloquent JavaScript](http://eloquentjavascript.net/) +* [JavaScript, JavaScript](http://javascriptweblog.wordpress.com/) +* [Hành trình Phát triển JavaScript](http://rmurphey.com/) +* [Cú giết hoàn hảo](http://perfectionkills.com/) +* [Douglas Crockford's Wrrrld Wide Web](http://www.crockford.com) +* [JS Assessment](https://github.com/rmurphey/js-assessment) + + + + +### Quy trình Build & Deployment + +Dự án luôn luôn chuẩn bị các chức năng để mã nguồn có thể kiểm tra phong cách, kiểm tra lỗi và nén lại để chuẩn bị cho sử dụng trong môi trường sản xuất. Để làm những việc này, [grunt](https://github.com/gruntjs/grunt) viết bởi Ben Alman là công cụ tốt nhất và chính thức thay thế cho thư mục "kits/" của repo này. + + + + +### Kiểm tra lỗi + +Dự án _phải_ có một sô cách để unit, reference, implementation hoặc functional testing. Use case demos KHÔNG ĐỦ TIÊU CHUẨN là "tests". Dưới đây là danh sách test frameworks, không có sản phẩm nào hơn sản phẩm nào cả. + +* [QUnit](http://github.com/jquery/qunit) +* [Jasmine](https://github.com/pivotal/jasmine) +* [Vows](https://github.com/cloudhead/vows) +* [Mocha](https://github.com/visionmedia/mocha) +* [Hiro](http://hirojs.com/) +* [JsTestDriver](https://code.google.com/p/js-test-driver/) +* [Buster.js](http://busterjs.org/) +* [Sinon.js](http://sinonjs.org/) + +## Mục lục + +* [Khoảng trắng](#whitespace) +* [Cú pháp đẹp](#spacing) +* [Kiểm tra Type (Trích từ jQuery Core Style Guidelines)](#type) +* [Kiểm tra tính điều kiện](#cond) +* [Phong cách thực tế](#practical) +* [Đặt tên](#naming) +* [Khác](#misc) +* [Đối tượng Native & Host](#native) +* [Chú thích](#comments) +* [Code Một Ngôn ngữ](#language) + + + +------------------------------------------------ + + +## Mở đầu + +Các phần dưới đây chỉ ra một phong cách _hợp lý_ cho phát triển JavaScript hiện đại và không có nghĩa là quy tắc. Nguyên tắc quan trọng nhất là **luật nhất quán của phong cách code**. Bất kể phong cách nào bạn chọn cho dự án của bạn, hãy coi đó là luật. Làm theo tài liệu này để đảm bảo tính nhất quán trong phong cách, khả năng đọc và bảo trì của dự án của bạn. + + + + + +## Hướng dẫn đến nhất quán trong phong cách + + +1. <a name="whitespace">Khoảng trắng</a> +- Không bao giờ dùng cả khoảng trắng và tab. +- Khi bắt đầu một dự án, trước khi viết bất cứ dòng code nào, hãy chọn giữa soft indents (khoảng trắng) hoặc là tab thật, coi đây là **luật**. +- Để tăng tính đọc, tôi luôn luôn đề xuất thiết lập cho trình soạn thảo của bạn khoảng lùi là 2 ký tự — điều này có nghĩa là lùi vào 2 khoảng trắng hoặc 2 khoảng trắng đại diện cho một tab. +- Nếu trình soạn thảo hỗ trợ, hãy luôn bật chế độ "hiển thị tàng hình". Lợi ích của việc này: +- Đảm bảo tính nhất quán +- Loại bỏ khoảng trắng thừa +- Loại bỏ dòng chỉ chứa khoảng trắng +- Commits và diffs dễ đọc hơn + + +2. <a name="spacing">Cú pháp đẹp</a> + +A. Dấu nháy, ngoặc, và xuống dòng + +```javascript + +// if/else/for/while/try luôn luôn có khoảng trắng, ngoặc nhọn và xuống nhiều dòng +// điều này đảm bảo tính đọc + +// 2.A.1.1 +// Ví dụ của một cú pháp chật chội + +if(condition) doSomething(); + +while(condition) iterating++; + +for(var i=0;i<100;i++) someIterativeFn(); + + +// 2.A.1.1 +// Sử dụng khoảng trắng để tăng khả năng đọc + +if ( condition ) { +// statements +} + +while ( condition ) { +// statements +} + +for ( var i = 0; i < 100; i++ ) { +// statements +} + +// Hoặc tốt hơn: + +var i, +length = 100; + +for ( i = 0; i < length; i++ ) { +// statements +} + +// Hoặc... + +var i = 0, +length = 100; + +for ( ; i < length; i++ ) { +// statements +} + +var prop; + +for ( prop in object ) { +// statements +} + + +if ( true ) { +// statements +} else { +// statements +} +``` + + +B. Khai báo, gán, function ( Tên biến, Expression, Constructor ) + +```javascript + +// 2.B.1.1 +// Biến +var foo = "bar", +num = 1, +undef; + +// Ký hiệu: +var array = [], +object = {}; + + +// 2.B.1.2 +// Chỉ sử dụng một `var` trong một scope (function) để tăng tính đọc +// và đảm bảo danh sách khai báo không bị lộn xộn (và cũng tiết kiệm được vài ký tự) + +// Không tốt +var foo = ""; +var bar = ""; +var qux; + +// Tốt +var foo = "", +bar = "", +quux; + +// hoặc.. +var // Chú thích vào đây +foo = "", +bar = "", +quux; + +// 2.B.1.3 +// var nên luôn luôn đặt ở đầu một scope (function). + + +// Không tốt +function foo() { + +// statements + +var bar = "", +qux; +} + +// Tốt +function foo() { +var bar = "", +qux; + +// statements sau khai báo. +} + +// 2.B.1.4 +// const và let, từ ECMAScript 6, cũng nên để ở đầu scope (một khối). + +// Không tốt +function foo() { +let foo, +bar; +if (condition) { +bar = ""; +// statements +} +} +// Tốt +function foo() { +let foo; +if (condition) { +let bar = ""; +// statements +} +} +``` + +```javascript + +// 2.B.2.1 +// Khai báo tên function +function foo( arg1, argN ) { + +} + +// Sử dụng +foo( arg1, argN ); + + +// 2.B.2.2 +// Khai báo tên function +function square( number ) { +return number * number; +} + +// Sử dụng +square( 10 ); + +// Đảm bảo sự liền mạch khi khai báo param +function square( number, callback ) { +callback( number * number ); +} + +square( 10, function( square ) { +// callback statements +}); + + +// 2.B.2.3 +// Khai báo bên trong function +var square = function( number ) { +// Return một thứ gì đó có giá trị và quan trọng +return number * number; +}; + +// Khai báo trong function với Identifier +// Cách này nên được sử dụng khi thêm giá trị vào chính bản thân nó +// và khả năng tự gọi, tự xác định bên trong stack traces: +var factorial = function factorial( number ) { +if ( number < 2 ) { +return 1; +} + +return number * factorial( number - 1 ); +}; + + +// 2.B.2.4 +// Khai báo Constructor +function FooBar( options ) { + +this.options = options; +} + +// Sử dụng +var fooBar = new FooBar({ a: "alpha" }); + +fooBar.options; +// { a: "alpha" } + +``` + + +C. Exceptions, Độ lệch nhẹ + +```javascript + +// 2.C.1.1 +// Functions với callbacks +foo(function() { +// Lưu ý là không có khoảng trắng bên trong param +// của function và từ khóa "function" +}); + +// Param của function là mảng, không có khoảng trắng +foo([ "alpha", "beta" ]); + +// 2.C.1.2 +// Param của function là đối tượng, không có khoảng trắng +foo({ +a: "alpha", +b: "beta" +}); + +// Một param là chuỗi, không có khoảng trắng +foo("bar"); + +// Nhóm bên trong dấu nháy, không khoảng trắng +if ( !("foo" in obj) ) { + +} + +``` + +D. Tính nhất quán luôn luôn thắng + +Trong phần 2.A-2.C, quy tắc về khoảng trắng được nhắc đến như là đề nghị với mục đích đơn giản và cao hơn: tính nhất quán. +Điều quan trọng là sự ưa thích, như là "khoảng trắng bên trong" nên được coi là không bắt buộc, nhưng nên áp dụng chỉ một phong cách duy nhất trong dự án của bạn. + +```javascript + +// 2.D.1.1 + +if (condition) { +// statements +} + +while (condition) { +// statements +} + +for (var i = 0; i < 100; i++) { +// statements +} + +if (true) { +// statements +} else { +// statements +} + +``` + +E. Dấu nháy + +Cho dù bạn thích nháy đơn hay nháy kép, điều đó không quan trọng, Javascript không đối xử khác nhau giữa 2 kiểu nháy này. Điều **CẦN PHẢI** làm là đảm bảo tính nhất quán. **Không bao giờ lẫn giữa các loại dấu nháy trong cùng một dự án. Chọn một kiểu và làm theo kiểu đó.** + +F. Hết dòng và dòng trắng + +Khoảng trắng có thể làm hỏng diffs và làm cho changesets không thể đọc được. Có thể sử dụng pre-commit hook để loại bỏ các khoảng trắng cuối dòng và khoảng trắng trên dòng rỗng tự động. + +3. <a name="type">Kiểm tra Type (Trích từ jQuery Core Style Guidelines)</a> + +A. Kiểm tra nghiêm ngặt + +String: + +typeof variable === "string" + +Number: + +typeof variable === "number" + +Boolean: + +typeof variable === "boolean" + +Object: + +typeof variable === "object" + +Array: + +Array.isArray( arrayLikeObject ) +(wherever possible) + +Node: + +elem.nodeType === 1 + +null: + +variable === null + +null hoặc undefined: + +variable == null + +undefined: + +Biến Global: + +typeof variable === "undefined" + +Biến Local: + +variable === undefined + +Properties: + +object.prop === undefined +object.hasOwnProperty( prop ) +"prop" in object + +B. Kiểm tra cưỡng chế + +Cho một đoạn code như sau... + +Có một đoạn HTML: + +```html + +<input type="text" id="foo-input" value="1"> + +``` + + +```javascript + +// 3.B.1.1 + +// `foo` được khai báo với giá trị `0` và kiểu là `number` +var foo = 0; + +// typeof foo; +// "number" +... + +// Đâu đó trong code của bạn, bạn cập nhật giá trị của `foo` +// với một giá trị mới lấy từ phần tử input + +foo = document.getElementById("foo-input").value; + +// Nếu bạn kiểm tra `typeof foo`, giá trị trả lại sẽ là `string` +// Điều này có nghĩa là nếu bạn có kiểm tra logic với `foo` như sau: + +if ( foo === 1 ) { + +importantTask(); + +} + +// `importantTask()` sẽ không bao giờ được gọi, mặc dù `foo` có giá trị "1" + + +// 3.B.1.2 + +// Bạn có thể sửa khắc phục điều này bằng cách sử dụng toán tử một ngôi (unary operator) + hoặc -: + +foo = +document.getElementById("foo-input").value; +// ^ toán tử một ngôi + sẽ chuyển giá trị bên phải thành số + +// typeof foo; +// "number" + +if ( foo === 1 ) { + +importantTask(); + +} + +// `importantTask()` sẽ được gọi +``` + +Một số tình huống thường gặp khác: + + +```javascript + +// 3.B.2.1 + +var number = 1, +string = "1", +bool = false; + +number; +// 1 + +number + ""; +// "1" + +string; +// "1" + ++string; +// 1 + ++string++; +// 1 + +string; +// 2 + +bool; +// false + ++bool; +// 0 + +bool + ""; +// "false" +``` + + +```javascript +// 3.B.2.2 + +var number = 1, +string = "1", +bool = true; + +string === number; +// false + +string === number + ""; +// true + ++string === number; +// true + +bool === number; +// false + ++bool === number; +// true + +bool === string; +// false + +bool === !!string; +// true +``` + +```javascript +// 3.B.2.3 + +var array = [ "a", "b", "c" ]; + +!!~array.indexOf("a"); +// true + +!!~array.indexOf("b"); +// true + +!!~array.indexOf("c"); +// true + +!!~array.indexOf("d"); +// false + +// Lưu ý là những phương pháp trên được coi là "thông minh không cần thiết" +// Sử dụng các phương pháp tiếp cận đảm bảo khác để so sánh giá trị như là +// indexOf, như sau: + +if ( array.indexOf( "a" ) >= 0 ) { +// ... +} +``` + +```javascript +// 3.B.2.4 + + +var num = 2.5; + +parseInt( num, 10 ); + +// bằng với... + +~~num; + +num >> 0; + +num >>> 0; + +// Tất cả đều trả lại kết quả là 2 + + +// Hãy lưu ý rằng, số âm sẽ được xử lý khác... + +var neg = -2.5; + +parseInt( neg, 10 ); + +// tương tự... + +~~neg; + +neg >> 0; + +// Tất cả đều trả lại kết quả là -2 +// Tuy nhiên... + +neg >>> 0; + +// Sẽ trả lại 4294967294 + + + + +``` + + + +4. <a name="cond">Kiểm tra tính điều kiện</a> + +```javascript + +// 4.1.1 +// Khi kiểm tra array có độ dài (length), +// thay vì: +if ( array.length > 0 ) ... + +// ...hãy làm như sau: +if ( array.length ) ... + + +// 4.1.2 +// Khi kiểm tra array rỗng, +// thay vì: +if ( array.length === 0 ) ... + +// ...hãy làm như sau: +if ( !array.length ) ... + + +// 4.1.3 +// Khi kiểm tra string không rỗng, +// thay vì: +if ( string !== "" ) ... + +// ...hãy làm như sau: +if ( string ) ... + + +// 4.1.4 +// Khi kiểm tra string _rỗng_, +// thay vì: +if ( string === "" ) ... + +// ...hãy kiểm tra độ sai, làm như sau: +if ( !string ) ... + + +// 4.1.5 +// Khi kiểm tra tham chiếu (reference) có đúng hay không, +// thay vì: +if ( foo === true ) ... + +// ...hãy kiểm tra chính giá trị của đối tượng, tận dụng khả năng sẵn có: +if ( foo ) ... + + +// 4.1.6 +// Khi kiểm tra tham chiếu có sai hay không, +// thay vì: +if ( foo === false ) ... + +// ...hãy kiểm tra độ sai +if ( !foo ) ... + +// ...Cẩn thận, đoạn code trên cũng đúng với: 0, "", null, undefined, NaN +// Nếu bạn _PHẢI_ kiểm tra giá trị boolean false, hãy dùng: +if ( foo === false ) ... + + +// 4.1.7 +// Khi kiểm tra tham chiếu có thể là null hoặc undefined, nhưng không phải là false, "" hoặc 0, +// thay vì: +if ( foo === null || foo === undefined ) ... + +// ...tận dụng độ lệch nhẹ == khi so sánh, như sau: +if ( foo == null ) ... + +// Hãy nhớ, sử dụng == để so sánh với `null` sẽ BẰNG với `null` và `undefined` +// chứ không phải là `false`, "" hoặc 0 +null == undefined + +``` +LUÔN LUÔN kiểm tra theo phương thức cho kết quả chính xác nhất - phương thức ở trên chỉ là hướng dẫn, không phải là giáo lý. + +```javascript + +// 4.2.1 +// Ghi chú về biểu thức ép buộc kiểu + +// Luôn dùng `===` thay vì `==` (ngoại trừ trường hợp yêu cầu biểu thức kiểu lỏng lẻo - loose type) + +// === không ép buộc kiểu, vì vậy: + +"1" === 1; +// false + +// == ép buộc kiểu, vì vậy: + +"1" == 1; +// true + + +// 4.2.2 +// Booleans, Đúng và Sai + +// Booleans: +true, false + +// Đúng: +"foo", 1 + +// Sai: +"", 0, null, undefined, NaN, void 0 + +``` + + +5. <a name="practical">Phong cách thực tế</a> + +```javascript + +// 5.1.1 +// Module thực tế + +(function( global ) { +var Module = (function() { + +var data = "secret"; + +return { +// Đây là một property kiểu boolean +bool: true, +// Giá trị string +string: "a string", +// Property là array +array: [ 1, 2, 3, 4 ], +// Property là Object +object: { +lang: "en-Us" +}, +getData: function() { +// lấy giá trị hiện tại của biến `data` +return data; +}, +setData: function( value ) { +// đặt giá trị cho `data` và trả lại giá trị đó +return ( data = value ); +} +}; +})(); + +// Một vài việc khác có thể xảy ra ở đây + +// biến module thành một Object Global +global.Module = Module; + +})( this ); + +``` + +```javascript + +// 5.2.1 +// Constructor trong thực tế + +(function( global ) { + +function Ctor( foo ) { + +this.foo = foo; + +return this; +} + +Ctor.prototype.getFoo = function() { +return this.foo; +}; + +Ctor.prototype.setFoo = function( val ) { +return ( this.foo = val ); +}; + + +// Để gọi constructor không cần `new`, bạn có thể làm như sau: +var ctor = function( foo ) { +return new Ctor( foo ); +}; + + +// biến constructor thành Object Global +global.ctor = ctor; + +})( this ); + +``` + + + +6. <a name="naming">Đặt tên</a> + + + +A. Bạn không phải là một bộ compiler mã máy, vì vậy đừng cố tả ra như vậy. + +Ví dụ sau đây là một sai lầm nghiêm trọng trong việc đặt tên: + +```javascript + +// 6.A.1.1 +// Ví dụ về code với cách đặt tên nghèo nàn + +function q(s) { +return document.querySelectorAll(s); +} +var i,a=[],els=q("#foo"); +for(i=0;i<els.length;i++){a.push(els[i]);} +``` + +Hy vọng là nếu bạn đang viết code như trên, thì hãy chấm dứt trong hôm nay. + +Đây là một đoạn code có cùng logic, nhưng với cách đặt tên có ý nghĩa hơn (cùng với cấu trúc dễ đọc): + +```javascript + +// 6.A.2.1 +// Ví dụ về cách đặt tên tốt hơn + +function query( selector ) { +return document.querySelectorAll( selector ); +} + +var idx = 0, +elements = [], +matches = query("#foo"), +length = matches.length; + +for ( ; idx < length; idx++ ) { +elements.push( matches[ idx ] ); +} + +``` + +Một số chỉ dẫn về cách đặt tên: + +```javascript + +// 6.A.3.1 +// Tên chuỗi + +`dog` là một chuỗi + + +// 6.A.3.2 +// Tên mảng + +`dogs` là một mảng của những chuỗi `dog` + + +// 6.A.3.3 +// Tên function, object, instance, vân vân + +camelCase; function và biến + + +// 6.A.3.4 +// Đặt tên constructor, prototype, vân vân + +PascalCase; tên constructor + + +// 6.A.3.5 +// Đặt tên regular expressions + +rDesc = //; + + +// 6.A.3.6 +// Hướng dẫn từ Google Closure Library Style Guide + +functionNamesLikeThis; +variableNamesLikeThis; +ConstructorNamesLikeThis; +EnumNamesLikeThis; +methodNamesLikeThis; +SYMBOLIC_CONSTANTS_LIKE_THIS; + +``` + +B. Ảnh hưởng của `this` + +Trong các trường hợp cơ bản sử dụng `call` và `apply`, nên luôn luôn dùng `.bind( this )` hoặc các cách tương tự, để tạo một `BoundFunction` cho sau này sử dụng. Chỉ sử dụng đặt tên khác cho `this` trong trường hợp bất khả kháng. + +```javascript + +// 6.B.1 +function Device( opts ) { + +this.value = null; + +// mở một async stream, +// đoạn dưới sẽ được gọi liên tục +stream.read( opts.path, function( data ) { + +// Cập nhật giá trị hiện tại của instance này +// với giá trị mới nhất +// từ data stream +this.value = data; + +}.bind(this) ); + +// Thay đổi tần số +setInterval(function() { + +// Gửi event +this.emit("event"); + +}.bind(this), opts.freq || 100 ); +} + +// Giả định rằng đã inherit EventEmitter ;) + +``` + +Khi không có `.bind`, có các function tương tự trong các thư viện Javascript hiện đại + + +```javascript +// 6.B.2 + +// ví dụ: lodash/underscore, _.bind() +function Device( opts ) { + +this.value = null; + +stream.read( opts.path, _.bind(function( data ) { + +this.value = data; + +}, this) ); + +setInterval(_.bind(function() { + +this.emit("event"); + +}, this), opts.freq || 100 ); +} + +// ví dụ jQuery.proxy +function Device( opts ) { + +this.value = null; + +stream.read( opts.path, jQuery.proxy(function( data ) { + +this.value = data; + +}, this) ); + +setInterval( jQuery.proxy(function() { + +this.emit("event"); + +}, this), opts.freq || 100 ); +} + +// ví dụ dojo.hitch +function Device( opts ) { + +this.value = null; + +stream.read( opts.path, dojo.hitch( this, function( data ) { + +this.value = data; + +}) ); + +setInterval( dojo.hitch( this, function() { + +this.emit("event"); + +}), opts.freq || 100 ); +} + +``` + +Trong tình huống cuối cùng, tạo một tên biến tham chiếu `this` như là `self` chẳng hạn. Trường hợp này hay tạo ra bug và nên tránh khi có thể. + +```javascript + +// 6.B.3 + +function Device( opts ) { +var self = this; + +this.value = null; + +stream.read( opts.path, function( data ) { + +self.value = data; + +}); + +setInterval(function() { + +self.emit("event"); + +}, opts.freq || 100 ); +} + +``` + + +C. Sử dụng `thisArg` + +Một số prototype method có sẵn của ES 5.1 có một biến đặc biệt `thisArg`, và nên sử dụng bất cứ khi nào có thể + +```javascript + +// 6.C.1 + +var obj; + +obj = { f: "foo", b: "bar", q: "qux" }; + +Object.keys( obj ).forEach(function( key ) { + +// |this| tham chiếu tới `obj` + +console.log( this[ key ] ); + +}, obj ); // <-- param cuối cùng là `thisArg` + +// In ra console... + +// "foo" +// "bar" +// "qux" + +``` + +`thisArg` còn có thể dùng với `Array.prototype.every`, `Array.prototype.forEach`, `Array.prototype.some`, `Array.prototype.map`, `Array.prototype.filter` + +7. <a name="misc">Khác</a> + +Phần này sẽ được dùng để mô tả ý tưởng và khái niệm không nên được coi là bắt buộc, nhưng được khuyến khích sử dụng trong thực tế để tìm ra cách tốt hơn để thực hiện các tác vụ trong lập trình Javascript. + +A. Nên tránh sử dụng`switch` + +Đã có những thay đổi lớn đến hiệu suất của `switch` trong các phiên bản mới nhất của Firefox và Chrome. +http://jsperf.com/switch-vs-object-literal-vs-module + +Những cải tiến đó cũng có thể xem ở đây: +https://github.com/rwldrn/idiomatic.js/issues/13 + +```javascript + +// 7.A.1.1 +// Ví dụ khi sử dụng `switch` + +switch( foo ) { +case "alpha": +alpha(); +break; +case "beta": +beta(); +break; +default: +// làm cái gì khác +break; +} + +// 7.A.1.2 +// Một cách khác để xử lý các trường hợp điều kiện +// là sử dụng một object lưu trữ các "trường hợp" và một function để xử lý: + +var cases, delegator; + +// Ví dụ chỉ có tính minh họa. +cases = { +alpha: function() { +// code xử lý +// trả lại dữ liệu +return [ "Alpha", arguments.length ]; +}, +beta: function() { +// code xử lý +// trả lại dữ liệu +return [ "Beta", arguments.length ]; +}, +_default: function() { +// code xử lý +// trả lại dữ liệu +return [ "Default", arguments.length ]; +} +}; + +delegator = function() { +var args, key, delegate; + +// Chuyển danh sách param thành một mảng +args = [].slice.call( arguments ); + +// Lấy key là trường hợp đúng +key = args.shift(); + +// Gán trường hợp mặc định +delegate = cases._default; + +// Chuyển đến trường hợp được chọn +if ( cases.hasOwnProperty( key ) ) { +delegate = cases[ key ]; +} + +// Param đầu tiên có thể là dữ liệu được sử dụng, +// trong trường hợp này, |null| sẽ được dùng +return delegate.apply( null, args ); +}; + +// 7.A.1.3 +// Sử dụng API từ 7.A.1.2: + +delegator( "alpha", 1, 2, 3, 4, 5 ); +// [ "Alpha", 5 ] + +// Tất nhiên, key của `trường hợp` có thể dựa trên +// các điều kiện phức tạp hơn + +var caseKey, someUserInput; + +// Có thể là lấy từ đầu vào (input)? +someUserInput = 9; + +if ( someUserInput > 10 ) { +caseKey = "alpha"; +} else { +caseKey = "beta"; +} + +// hoặc là... + +caseKey = someUserInput > 10 ? "alpha" : "beta"; + +// Sau đó... + +delegator( caseKey, someUserInput ); +// [ "Beta", 1 ] + +// và tất nhiên là... + +delegator(); +// [ "Default", 0 ] + + +``` + +B. Return sớm tăng khả năng đọc của code với tăng hiệu năng nhỏ + +```javascript + +// 7.B.1.1 +// Không tốt: +function returnLate( foo ) { +var ret; + +if ( foo ) { +ret = "foo"; +} else { +ret = "quux"; +} +return ret; +} + +// Tốt: + +function returnEarly( foo ) { + +if ( foo ) { +return "foo"; +} +return "quux"; +} + +``` + + +8. <a name="native">Đối tượng Native & Host</a> + +Nguyên tắc cơ bản: + +### Đừng làm điều ngu ngốc và mọi thứ sẽ không sao cả. + +Để đảm bảo nguyên tắc trên, hãy đọc phần bên dưới: + +#### “Everything is Permitted: Extending Built-ins” (Tất cả đều cho phép: Mở rộng thành phần dựng sẵn) viết bởi Andrew Dupont (JSConf2011, Portland, Oregon) + +<iframe src="http://blip.tv/play/g_Mngr6LegI.html" width="480" height="346" frameborder="0" allowfullscreen></iframe><embed type="application/x-shockwave-flash" src="http://a.blip.tv/api.swf#g_Mngr6LegI" style="display:none"></embed> + +http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permitted-extending-built-ins-5211542 + + +9. <a name="comments">Chú thích</a> + +#### Dòng đầu tiên trên code là tiêu đề +#### Nhiều dòng cũng tốt +#### Chú thích cuối dùng là không được phép! +#### Chú thích theo JSDoc cũng hay, nhưng cần thời gian để nghiên cứu + + +10. <a name="language">Code Một Ngôn Ngữ</a> + +Chương trình chỉ nên viết bằng một ngôn ngữ, cho dù đó là ngôn ngữ nào, quyết định bởi một hay nhiều người duy trì dự án. + +## Phụ lục + +### Dấu phẩy đầu tiên. + +Bất kỳ dự án nào trích dẫn tài liệu này như là một hướng dẫn về phong cách code sẽ không chấp nhận phong cách dấu phẩy đầu tiên, trừ khi là được quy định bởi tác giả của dự án. + + + +---------- + + +<a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/80x15.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Nguyên tắc để Viết Javascript Nhất quán</span> viết bởi <a xmlns:cc="http://creativecommons.org/ns#" href="https://github.com/rwldrn/idiomatic.js" property="cc:attributionName" rel="cc:attributionURL">Rick Waldron và Những người đóng góp</a> được cấp phép <a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US">Creative Commons Attribution 3.0 Unported License</a>.<br />Dựa trên tài liệu ở <a xmlns:dct="http://purl.org/dc/terms/" href="https://github.com/rwldrn/idiomatic.js" rel="dct:source">github.com/rwldrn/idiomatic.js</a>. diff --git a/translations/zh_CN/readme.md b/translations/zh_CN/readme.md index 5d8680b2..08e79710 100644 --- a/translations/zh_CN/readme.md +++ b/translations/zh_CN/readme.md @@ -23,6 +23,7 @@ * Sofish Lin [@sofish](http://twitter.com/sofish), [github](https://github.com/sofish) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) * Miloš Gavrilović [@gavrisimo](http://twitter.com/gavrisimo), [github](https://github.com/gavrisimo) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## 无论有多少人在维护,所有在代码仓库中的代码理应看起来像同一个人写的。 diff --git "a/translations/\321\201\321\200_\320\241\320\240/readme.md" "b/translations/\321\201\321\200_\320\241\320\240/readme.md" index b5ebc06f..d3253b96 100644 --- "a/translations/\321\201\321\200_\320\241\320\240/readme.md" +++ "b/translations/\321\201\321\200_\320\241\320\240/readme.md" @@ -21,6 +21,7 @@ * Alex Navasardyan [@alexnavasardyan](http://twitter.com/alexnavasardyan), [github](https://github.com/2k00l) * Mihai Paun [@mihaipaun](http://twitter.com/mihaipaun), [github](https://github.com/mihaipaun) * Дејан Димић [@dejan_dimic](http://twitter.com/dejan_dimic), [github](https://github.com/rubystream) +* Duc Nguyen [@ducntq](https://twitter.com/ducntq), [github](https://github.com/ducntq) ## Сав код у било којој "бази кода" требало би да изгледа као да га је написала једна особа, без обзира колико је људи допринело његовом креирању.