|
1 | 1 | # 一貫性のある慣用的なJavaScriptの書き方
|
2 | 2 |
|
| 3 | + |
3 | 4 | ## これは継続しているドキュメントであるため、私たちのコードを改善できる新しいアイデアを常に歓迎します。貢献方法: fork、clone、branch、commit、push、pull request。
|
4 | 5 |
|
5 | 6 | * Rick Waldron [@rwaldron](http://twitter.com/rwaldron), [github](https://github.com/rwldrn)
|
|
16 | 17 | * Ryuichi Okumura [@okuryu](http://twitter.com/okuryu), [github](https://github.com/okuryu)
|
17 | 18 | * Pascal Precht [@PascalPrecht](http://twitter.com/PascalPrecht), [github](https://github.com/pascalprecht)
|
18 | 19 | * 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
|
| 20 | +* Marco Trulla [@marcotrulla](http://twitter.com/marcotrulla), [github](https://github.com/Ragnarokkr) |
| 21 | +* Alex Navasardyan [@alexnavasardyan](http://twitter.com/alexnavasardyan), [github](https://github.com/2k00l) |
| 22 | + |
19 | 23 |
|
20 | 24 | ## どんなに多くの人が貢献したとしても、どのコードも一人で書いたようにするべきです。
|
21 | 25 |
|
22 | 26 | ### 次の項目では私のすべてのコードで使用しているプラクティスを説明しているため、私のプロジェクトに貢献する場合はこれらのガイドラインを理解していなければなりません。
|
23 | 27 |
|
24 |
| -### 私は皆さんのコードに私のスタイルを押し付けるつもりはありませんし、もしすでに共通のスタイルがあるのであればそちらを順守すべきです。 |
| 28 | +### 私は皆さんのコードやプロジェクトに私のスタイルを押し付けるつもりはありませんし、もしすでに共通のスタイルがあるのであればそちらを順守すべきです。 |
| 29 | + |
25 | 30 |
|
26 |
| -> "成功を収めるプロジェクトをうまく管理することの一つが自分でコードを書いて実現するということではありません。もし多くの人があなたのコードを利用しているなら、仕様の中にはあなたの好みではなく、最大限に明確なコードを書きましょう。" - Idan Gazit |
| 31 | +> ### "スタイルに関する議論は無意味です。ここにあるスタイルガイドにあなたは従うべきです。" |
| 32 | +>_Rebecca_ _Murphey_ |
27 | 33 |
|
| 34 | + |
| 35 | + |
| 36 | +> ### "成功を収めるプロジェクトをうまく管理することの一つが自分でコードを書いて実現するということではありません。もし多くの人があなたのコードを利用しているなら、仕様の中にはあなたの好みではなく、最大限に明確なコードを書きましょう。" - Idan Gazit |
| 37 | +>_Idan_ _Gazit_ |
28 | 38 |
|
29 | 39 | ## 翻訳
|
30 | 40 |
|
| 41 | +* [ドイツ語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/de_DE) |
31 | 42 | * [フランス語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/fr_FR)
|
32 | 43 | * [スペイン語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/es_ES)
|
33 | 44 | * [ポルトガル語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/pt_BR)
|
34 | 45 | * [韓国語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ko_KR)
|
35 | 46 | * [日本語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ja_JP)
|
| 47 | +* [イタリア語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/it_IT) |
| 48 | +* [ロシア語](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ru_RU) |
| 49 | + |
36 | 50 |
|
37 | 51 | ## 慣用的ではないもの(重要):
|
38 | 52 |
|
39 |
| -### コードの品質: 素晴らしいツールや情報とリファレンス |
| 53 | +### コードの品質ツールや情報とリファレンス |
40 | 54 |
|
41 | 55 | * [jsPerf](http://jsperf.com/)
|
42 | 56 | * [jsFiddle](http://jsfiddle.net/)
|
|
45 | 59 | * [jshint](http://jshint.com/)
|
46 | 60 | * [jslint](http://jslint.org/)
|
47 | 61 |
|
48 |
| -[Anton KovalyovによるLeveraging Code Quality Tools](http://anton.kovalyov.net/slides/gothamjs/) |
49 |
| - |
50 | 62 |
|
51 |
| -### 賢くなろう |
| 63 | +## 賢くなろう |
52 | 64 |
|
53 |
| -[http://es5.github.com/](http://es5.github.com/) |
| 65 | +### [Annotated ECMAScript 5.1](http://es5.github.com/) |
| 66 | +### [EcmaScript Language Specification, 5.1 Edition](http://ecma-international.org/ecma-262/5.1/) |
54 | 67 |
|
55 | 68 | 下記の事項は 1) 不完全、2) *必読*ということを熟考しなければなりません。私はこれらの作者によるスタイルに常に同意はしていませんが、彼らは一貫性があるため信頼できるのも確かです。その上、これらは言語の世界では権威があるものです。
|
56 | 69 |
|
|
61 | 74 | * [Perfection Kills](http://perfectionkills.com/)
|
62 | 75 | * [Douglas Crockford's Wrrrld Wide Web](http://www.crockford.com)
|
63 | 76 | * [JS Assessment](https://github.com/rmurphey/js-assessment)
|
| 77 | + * [Leveraging Code Quality Tools by Anton Kovalyov](http://anton.kovalyov.net/slides/gothamjs/) |
| 78 | + |
| 79 | + |
64 | 80 |
|
65 | 81 |
|
66 | 82 | ### ビルドとデプロイのプロセス
|
|
446 | 462 | ```
|
447 | 463 |
|
448 | 464 |
|
449 |
| - ```js |
| 465 | + ```javascript |
450 | 466 |
|
451 | 467 | // 3.B.1.1
|
452 | 468 |
|
|
821 | 837 | 6. <a name="naming">ネーミング</a>
|
822 | 838 |
|
823 | 839 |
|
824 |
| - あなたがコードをコンパイルしたり圧縮したりするわけではないので、そういった事をしようとしてはいけません。 |
| 840 | + A. あなたがコードをコンパイルしたり圧縮したりするわけではないので、そういった事をしようとしてはいけません。 |
825 | 841 |
|
826 | 842 | 次のコードはひどいネーミングの例です:
|
827 | 843 |
|
828 | 844 | ```javascript
|
829 | 845 |
|
830 |
| - // 6.1.1 |
| 846 | + // 6.A.1.1 |
831 | 847 | // 悪い名前を使ったコードの例
|
832 | 848 |
|
833 | 849 | function q(s) {
|
|
843 | 859 |
|
844 | 860 | ```javascript
|
845 | 861 |
|
846 |
| - // 6.2.1 |
| 862 | + // 6.A.2.1 |
847 | 863 | // 改善したネーミングを使ったコードの例
|
848 | 864 |
|
849 | 865 | function query( selector ) {
|
|
855 | 871 | matches = query("#foo"),
|
856 | 872 | length = matches.length;
|
857 | 873 |
|
858 |
| - for( ; idx < length; idx++ ){ |
| 874 | + for ( ; idx < length; idx++ ) { |
859 | 875 | elements.push( matches[ idx ] );
|
860 | 876 | }
|
861 | 877 |
|
|
865 | 881 |
|
866 | 882 | ```javascript
|
867 | 883 |
|
868 |
| - // 6.3.1 |
| 884 | + // 6.A.3.1 |
869 | 885 | // 文字列のネーミング
|
870 | 886 |
|
871 | 887 | `dog` は文字列です
|
872 | 888 |
|
873 | 889 |
|
874 |
| - // 6.3.2 |
| 890 | + // 6.A.3.2 |
875 | 891 | // 配列のネーミング
|
876 | 892 |
|
877 | 893 | `dogs` は `dog` という文字列の配列です
|
878 | 894 |
|
879 | 895 |
|
880 |
| - // 6.3.3 |
| 896 | + // 6.A.3.3 |
881 | 897 | // 関数、オブジェクト、インスタンスなどのネーミング
|
882 | 898 |
|
883 | 899 | camelCase; function と var による宣言
|
884 | 900 |
|
885 | 901 |
|
886 |
| - // 6.3.4 |
| 902 | + // 6.A.3.4 |
887 | 903 | // コンストラクターやプロトタイプなどのネーミング
|
888 | 904 |
|
889 | 905 | PascalCase; コンストラクター
|
890 | 906 |
|
891 | 907 |
|
892 |
| - // 6.3.5 |
| 908 | + // 6.A.3.5 |
893 | 909 | // 正規表現のネーミング
|
894 | 910 |
|
895 | 911 | rDesc = //;
|
896 | 912 |
|
897 | 913 |
|
898 |
| - // 6.3.6 |
| 914 | + // 6.A.3.6 |
899 | 915 | // Google Closure Library Style Guideより
|
900 | 916 |
|
901 | 917 | functionNamesLikeThis;
|
|
905 | 921 | methodNamesLikeThis;
|
906 | 922 | SYMBOLIC_CONSTANTS_LIKE_THIS;
|
907 | 923 |
|
| 924 | + ``` |
| 925 | + |
| 926 | + B. `this` の扱い |
| 927 | + |
| 928 | + 後から呼び出される `BoundFunction` を定義する場合は `call` や `apply` の一般的な使われ方よりも `.bind( this )` や同等の機能が好ましいです。好ましいオプションがない場合だけ、別の方法を考えましょう。 |
| 929 | + |
| 930 | + ```javascript |
| 931 | +
|
| 932 | + // 6.B.1 |
| 933 | + function Device( opts ) { |
| 934 | +
|
| 935 | + this.value = null; |
| 936 | +
|
| 937 | + // これは非同期のストリームをオープンし |
| 938 | + // 継続的に呼び出されます |
| 939 | + stream.read( opts.path, function( data ) { |
| 940 | +
|
| 941 | + // このインスタンスの現在の値を |
| 942 | + // データストリームの最新の値で更新します |
| 943 | + this.value = data; |
| 944 | +
|
| 945 | + }.bind(this) ); |
| 946 | +
|
| 947 | + // デバイスのインスタンスから頻繁に発行される |
| 948 | + // イベントを絞ります |
| 949 | + setInterval(function() { |
| 950 | +
|
| 951 | + // 絞ったイベントを発行します |
| 952 | + this.emit("event"); |
| 953 | +
|
| 954 | + }.bind(this), opts.freq || 100 ); |
| 955 | + } |
| 956 | +
|
| 957 | + // EventEmitterを継承したかのように装います ;) |
| 958 | +
|
| 959 | + ``` |
| 960 | + |
| 961 | + もし利用できない場合でも最近の多くのJavaScriptライブラリには `.bind` と同様な機能があります。 |
| 962 | + |
| 963 | + |
| 964 | + ```javascript |
| 965 | + // 6.B.2 |
| 966 | +
|
| 967 | + // 例)lodash/underscoreの_.bind() |
| 968 | + function Device( opts ) { |
| 969 | +
|
| 970 | + this.value = null; |
| 971 | +
|
| 972 | + stream.read( opts.path, _.bind(function( data ) { |
| 973 | +
|
| 974 | + this.value = data; |
| 975 | +
|
| 976 | + }, this) ); |
| 977 | +
|
| 978 | + setInterval(_.bind(function() { |
| 979 | +
|
| 980 | + this.emit("event"); |
| 981 | +
|
| 982 | + }, this), opts.freq || 100 ); |
| 983 | + } |
| 984 | +
|
| 985 | + // 例)jQuery.proxy |
| 986 | + function Device( opts ) { |
| 987 | +
|
| 988 | + this.value = null; |
| 989 | +
|
| 990 | + stream.read( opts.path, jQuery.proxy(function( data ) { |
| 991 | +
|
| 992 | + this.value = data; |
| 993 | +
|
| 994 | + }, this) ); |
908 | 995 |
|
| 996 | + setInterval( jQuery.proxy(function() { |
| 997 | +
|
| 998 | + this.emit("event"); |
| 999 | +
|
| 1000 | + }, this), opts.freq || 100 ); |
| 1001 | + } |
| 1002 | +
|
| 1003 | + // 例)dojo.hitch |
| 1004 | + function Device( opts ) { |
| 1005 | +
|
| 1006 | + this.value = null; |
| 1007 | +
|
| 1008 | + stream.read( opts.path, dojo.hitch( this, function( data ) { |
| 1009 | +
|
| 1010 | + this.value = data; |
| 1011 | +
|
| 1012 | + }) ); |
| 1013 | +
|
| 1014 | + setInterval( dojo.hitch( this, function() { |
| 1015 | +
|
| 1016 | + this.emit("event"); |
| 1017 | +
|
| 1018 | + }), opts.freq || 100 ); |
| 1019 | + } |
| 1020 | +
|
| 1021 | + ``` |
| 1022 | + |
| 1023 | + 最後の回避方法は、識別子として`this`への別名に`self`を使うことですが、これは極端なバグになる傾向があるため、可能な限り避けるべきです。 |
| 1024 | + |
| 1025 | + ```javascript |
| 1026 | +
|
| 1027 | + // 6.B.3 |
| 1028 | +
|
| 1029 | + function Device( opts ) { |
| 1030 | + var self = this; |
| 1031 | +
|
| 1032 | + this.value = null; |
| 1033 | +
|
| 1034 | + stream.read( opts.path, function( data ) { |
| 1035 | +
|
| 1036 | + self.value = data; |
| 1037 | +
|
| 1038 | + }); |
| 1039 | +
|
| 1040 | + setInterval(function() { |
| 1041 | +
|
| 1042 | + self.emit("event"); |
| 1043 | +
|
| 1044 | + }, opts.freq || 100 ); |
| 1045 | + } |
| 1046 | +
|
| 1047 | + ``` |
| 1048 | + |
| 1049 | + |
| 1050 | + C. `thisArg`を使う |
| 1051 | + |
| 1052 | + ES 5.1の各プロトタイプのメソッドでは特別な`thisArg`という署名に対応しています。これは可能な限り利用するべきです。 |
| 1053 | + |
| 1054 | + ```javascript |
| 1055 | +
|
| 1056 | + // 6.C.1 |
| 1057 | +
|
| 1058 | + var obj; |
| 1059 | +
|
| 1060 | + obj = { f: "foo", b: "bar", q: "qux" }; |
| 1061 | +
|
| 1062 | + Object.keys( obj ).forEach(function( key ) { |
| 1063 | +
|
| 1064 | + // |this|は`obj`への参照 |
| 1065 | +
|
| 1066 | + console.log( this[ key ] ); |
| 1067 | +
|
| 1068 | + }, obj ); // <-- 最後の引数が`thisArg` |
| 1069 | +
|
| 1070 | + // 結果は... |
| 1071 | +
|
| 1072 | + // "foo" |
| 1073 | + // "bar" |
| 1074 | + // "qux" |
909 | 1075 |
|
910 | 1076 | ```
|
911 | 1077 |
|
| 1078 | + `thisArg`は`Array.prototype.every`、`Array.prototype.forEach`、`Array.prototype.some`、`Array.prototype.map`、`Array.prototype.filter`と一緒に利用できます。 |
| 1079 | + |
912 | 1080 | 7. <a name="misc">雑則</a>
|
913 | 1081 |
|
914 | 1082 | このセクションは偏見的と見なされるべきではないアイデアやコンセプトを説明する代わりに、一般的なプログラミングタスクを行うためのより良い方法を見つけるためのプラクティスを助長するものです。
|
|
0 commit comments