Hatena::ブログ(Diary)

杉風呂2.0 - A Lifelog -

2014-11-03(月)

[]エンジニアが事業計画を知らなくてモノが作れるのか?

駄文ポエムです。

  • 先のことなんてわからないし、事業計画通りにいくわけがない。だがしかし
    • 何ヶ月後にどのくらいのユーザを集めたいのか、それがどれくらいのトランザクションを発生させるのか知らなくて作れる?
    • たとえYAGNIといっても直近作るfeatureぐらいは知っているべき
  • 事業規模に合わせて段階的にスケールさせていけばいいが、そのタイミングがいつなのか知っているか?
    • プロトタイプレベルの実装とプロダクションレベルの実装は違う
    • 機能が変われば最適なデータモデルやアプリケーションアーキテクチャも違う
    • チーム体制だって違う
  • エンジニアは、トレードオフを都度判断し、決定する
    • エンジニアリング上の判断がサービスの成長や企業の収益に直結する時代
    • 設計を統合したり、ビジネスサイドや経営層にリスクを説明したり諸々提案、交渉する役割を担う人が重要
  • プログラミングできればそれで満足なエンジニアなんてほとんどいない
    • サービスが提供する価値は何か、自分のやったことが会社にどういった利益をもたらすのか、世の中にどう役立つのかを知らないで仕事できないよね
    • にんげんだもの

2012-07-08(日)

[][]もっと上手に JavaScript を書くための 10 の Tips (10 tips to write better JavaScript)

この文章は、 Kinesis framework の公式ブログから "10 tips to write better JavaScript" という記事を翻訳したものです。今回は原文を並記してみます。実験的に GituHub で作業をしていたところsakuro さんからご指摘頂きました。GitHubは素晴らしいですね。

10 tips to write better JavaScript

http://kinesis.io/blog/10-tips-to-write-better-javascript/

1. セミコロンを忘れない(Don’t forget the semi-colons)

JavaScript allows developers the freedom to skip semi-colons in the source code. Most of us, being lazy as we are, tend to follow this.

However, the JavaScript compiler still needs them, so it is the parsers job to insert them whenever there is a parse error due to a missing semi-colon. It tries to execute the statement, and if it fails, it tries again with the semicolons

When you’re writing JavaScript, you should always include semicolons after statements.

JavaScript では、開発者がソースコード中のセミコロンを飛ばす自由がある。ほとんどの人は、私たちがそうであるように、怠け者なので、そうしがちだ。

しかし、JavaScriptコンパイラは依然としてセミコロンを必要としていて、セミコロンがないところでパースエラーがあると必ず、パーサがセミコロンを挿入する。ステートメントを実行しようとして失敗すると、セミコロンから実行を再開しようとする。

JavaScript を書くときは、ステートメントの後ろにかならずセミコロンを含めるべきだ。

2. 言語をよく知る(Know the language)

When we talk about Arrays and Objects in JavaScript, there are two ways to initializing them listed below.

JavaScript で Array とObject の話題といえば、以下のように、2 種類の初期化の方法がある。

var arr = [], obj = {};

var arr = new Array, obj = new Object;

だ。

Note that in modern browsers, the first way is faster and should be used.

モダンなブラウザでは、最初の方が高速なので、こちらを使うべきだ。

3. For ループ 対 For in ループ (For vs For in Loop)

The for in loop looks like

ループで使用する for はこんな感じだ。

for(item in obj) {
 //do something with item
}

This has a drawback. It will not just access the properties of “obj”, it will also include any properties inherited by the object through the prototype chain.

Therefore, most of the times, we have to use a if statement inside the loop along with the method “hasOwnProperty()” on the “obj”.

これには欠点がある。アクセスを許すプロパティが obj のものだけではないということだ。プロトタイプチェーンによって継承したプロパティをすべて含んでいるということでもある。

そのため、大抵は、ループ中の obj に対して hasOwnProperty() メソッドと一緒に if ステートメントを使わなくてはいけない。

4. == の代わりに === を使う(Use === instead of ==)

The identity (===) operator behaves identically to the equality (==) operator except no type conversion takes place. The types must be the same for === to return true.

The == operator will compare for equality after doing any necessary type conversions. The === operator will not do the conversion, so if two values are not the same type === will simply return false. It’s this case where === will be faster, and may return a different result than ==. In all other cases performance will be the same.

'===' 演算子は、等値か判断するのに必要な変換を行ってから比較を行う。'==' 演算子は変換をしない。2 つの値が同じ型でない場合、 '===' は単純に false を返す。'===' が速いのは事実だし、'==' と異なる結果を返すこともあるが、それ以外のすべての場合で、パフォーマンスは同じだ。

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

5. with の使用を避ける(Avoid using “with”)

JavaScript’s with statement was intended to provide a shorthand for writing recurring accesses to objects. So instead of writing

JavaScript の with ステートメントは、オブジェクトに繰り返しアクセスするための略記法を提供するためのものだ。次のように書く代わりに、

a.s.d.f.g.h.j.k.hello = true;
a.s.d.f.g.h.j.k.world = true;

You can write

このように書ける。

with (a.s.d.f.g.h.j.k) {
    hello = true;
    world = true;
}

How can you be sure if the variable a.s.d.f.g.h.j.k.hello is being set or a global variable named hello is being set.

Fortunately, we have a better way of doing this.

a.s.d.f.g.h.j.k.hello という変数がセットされるか、hello というグローバル変数がセットされるか自信を持って言えるだろうか。

幸運にも、これをやるよいやり方がある。

var obj = a.s.d.f.g.h.j.k;
obj.hello = true;
obj.world = true;

6. メソッド呼び出しを避ける(できるかぎり)(Avoid method calls (as much as you can))

Inline code is faster in all modern browsers that calling functions. I know that writing code in this manner can lead to clutter, but this is just one those JavaScript annoyances that we deal with.

インラインコードはすべてのモダンプラウザ関数呼び出しを行うよりも速い。私はこの方法が散らかりの元となると知ってはいるが、これは JavaScript のいらいらを扱う一つの方法でもある。

function explicitCall() {
  function cube(x) { return x * x * x };
  var i = 1000;

  while(i--) { console.info(cube(i)); }

}

function inlineCall() {
  var i = 1000;

  while(i--) { console.info(i * i * i); }

}

7. JSLinst を使う(Use JSLint)

http://www.jslint.com/ is The JavaScript Code Quality Tool.

Use this and check your JavaScript for errors as much as you can. Running your code through this is a great way to improve your code and follow the best practices.

http://www.jslint.com/JavaScript の品質測定ツールだ。

これを使って、 JavaScript のエラーをできるだけチェックしよう。この中に自分のコードを走らせれば、コードを改善し、ベストプラクティスに従う素晴らしい方法になる。

8. ドット記法と数値型(Dot Notation and Numbers)

There is a problem in the JavaScript parsers dot notation when dealing with numbers.

JavaScript のパーサは、数値を扱う際のドット記法に問題がある。

10.toString() //Error

The JavaScript parser expects a number to follow right after the first period. This causes a syntax error.

JavaScript のパーサは、最初のピリオドの右側に数字を期待している。これがシンタックスエラーを引き起こす。

To fix this, there are two ways of going forward

これを正すには、次のように 2 つのやり方がある。

(10).toString();
10..toString();

9. ブロックスコープが存在しない(No block scope)

There is no block scope in JavaScript.

Statements like if and for do not create a scope, and therefore variables can be overwritten.

In the following code, we will see how the value changes if the variable x

JavaScript にはブロックスコープが存在しない。

if や for といったステートメントはスコープを作らない。それため、変数は上書きされる可能性がある。

次のコードで、変数 x の値が変更される様子がわかるだろう。

var x = 1; // x = 1

if(true) {
 x = 2; // x = 2

 for(var i=0; i < 4; i++) {
  x = i; //i = 0,1,2,3
 }

}

So x is changing as the code executes.

変数 x がコードの実行とともに変化していく。

10. グローバル変数キャッシュする(Cache Globals)

It is always better when caching globals in terms of execution time.

実行時間の観点から、グローバル変数キャッシュした方がよい場合が多い。

function notcached() {
 var i = 1000;
 while (i--) window.test = 'test';
}

function cached() {
 var i = 1000;
 var w = window;
 while (i--) w.test = 'test';
}
JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法

2011-11-17(木)

[]あなたはJavaScriptを知らない

この記事はMichael Woloszynowicz氏のブログWeb 2.0 Development And Business Lessonsの記事"You Don’t Know JavaScript"を翻訳したものです。本人の許可を得て公開します。原文は2011年4月16日にポストされました。私自身のJavaScriptの学習が浅く、誤訳の指摘等はコメントを下さると助かります。

原文は以下のURLから。

http://www.w2lessons.com/2011/04/you-dont-know-javascript.html

去年ぐらいから、いらいらする現象が目に留まるようになった。プログラマが、少ししか触っていない技術でありながら、それで履歴書を脚色するパターンに何度も出会った。多くの言語で起こることではあるが、最も冒涜を受けている言語がJavaScriptだ。

あなたは自分が知らないということを知らない

この理由は、だいたいすべてのWeb開発者が1つぐらいはJavaScriptを扱う必要に出くわすからだ。理解もしないでJavaScriptを憶える最もありふれたアプローチとして、その場しのぎにサンプルコードを探してきてコピペするのだ。この手の'学習'で問題なのは、開発者が実際にはその言語を学んでおらず、その上、自分がそれを知っている錯覚してしまうことだ。何年もJavaScriptで仕事をして学んできた過程でわかったのは、本当に理解するようになってはじめて、知らないということがわかるということだ。このことはある種、循環した話であり、あなたに本当に必要なのは、自分がわかっていないということを教えてくれる人であり、本当の学習だ。サンプルコードをつなぎあわせただけの単純なonClickハンドラやformバリデーションしかやったことがないのに、誇らしげにJavaScriptを履歴書にリストアップした誰かさんとたくさん面接をしすぎている。jQueryやDojoのようなフレームワークを使い知るということはいいことだが、それらの背後にあるJavaScriptを正しく理解することなしには、それらのツールキットをマスターすることはないだろう。JavaScriptの多くの要素を表現するのに、私が基本レベル、中級レベル、上級レベルの知識だと思う考えを以下に示す。

JavaScript理解の基本レベル

  • 基本的なプログラミングのツール、例えば、ループやifステートメント、try/catchなどを知る。
  • 関数定義と適用に様々な方法があることを知る。無名関数も同様。
  • 基本的なスコープ定義の原則、グローバルスコープ(window) 対オブジェクトスコープ(closure)を理解する。
  • コンテキストの役割とthis変数の使い方を理解する。
  • オブジェクトのインスタンス化と宣言の様々なやり方を理解する。関数オブジェクトであるということも同様。
  • JavaScriptの比較演算子、例えば、'<'、'>'、'=='、'==='で何がfalseになるか、オブジェクトとstringがどのようにして比較されるかを理解する。キャストも同様。
  • Arrayがオブジェクトの属性と関数をどうインデクシングしているかと、それが本当の配列とどう違うか。(オブジェクトリテラル対配列リテラル)。

JavaScript理解の中級レベル

  • タイマーがどう動くか、つまり、いつどのようにして利用できるようになるかを理解する。非同期メソッド呼び出しも同様。
  • コールバックと関数適用を深く知る。例えば、'call'と'apply'メソッドでコンテキストを操作して、関数を引数として渡すことなど(function argument passing)。
  • JSON記法とeval関数を理解する。
  • クロージャがコードのパフォーマンスにどのように影響し、プライベート変数を作成するのにどのように利用されるかを理解する。
  • 愛くるしい(lovely)、(function(){})() 呼び出しに慣れ親しむ。
  • AJAXとオブジェクトのシリアライズ

JavaScriptの理解の上級レベル

(訳注:この段落は具体的な状況があまり思い浮かばず、かなり怪しい部分もあるのでJS上級者は原文を参照ください。)

  • メソッドのarguments変数を理解し、それがどのように使われて、arguments.lengthによって関数のオーバーロードを行えるかや、arguments.calleeによって再帰呼び出しを行えるか。arguments.calleeの使用が、ECMAScript 5のStrictモードがサポートしていない*1ことからもわかるように、危険なことだということを付け加えておこう。jQuery(バージョン1.4まで)とDojoの両者がそれを利用していようともだ。
  • 自己メモ化、カリー化、関数の部分適用のような高等なクロージャの使い方
  • 関数とhtmlプロトタイピング、つまりプロトタイプチェーンと基本的なJavaScriptオブジェクト関数(例:Array)を使ってコードを小さくすること。
  • Object型、instanceofとtypeofの使い方
  • 正規表現と正規表現コンパイル
  • withステートメントと、なぜそれを使うべきでないか
  • 最も難しいのは、それらのツールすべてを結びつけて、きれいで(clean)、堅牢で、速くメンテナンスしやすい、クロスブラウザ対応のコードに仕上げることだ。

上級レベルの最後のポイントはとりわけ重要であり、最も到達するのが難しい。JavaScriptの怠慢な性質を考えれば、自分のアプリケーションをメンテナンスできないスパゲッティコードの悪循環へとたやすく陥れてしまう。いったんJavaScriptという言語自身を学べば、それを体系化し、大きなアプリケーションのコンテキストにおいて互いに結びづけることができるようになって、真にマスターできるだろう。それには数年間の訓練と失敗が必要であり、本1冊では精通することができない。私自身は、JavaScriptを日常的に毎日数時間、数年間使用していて、自分のコードを書くのにより良い方法を見つけようとし続けているところだ。

こういった理由で、なにかのフレームワークに一足飛びにジャンプすることは危険であるし、jQueryのコードはメンテナンス不可能になる傾向がある。Dojoは自身のクラスとパッケージシステムによって、これを助長する。

JavaScriptはNode.jsなどによりいまやバックエンドまで浸透しているので、上に挙げた要件は、web特有の知識から分離することにした。webの側面(つまりDOMとIE)はJavaScriptに悪い名前を与え、すべてのプログラマを震え上がらせ、くらくらさせてきた。JavaScriptをwebのコンテキストで使おうとするならば、すべての良い開発者が知るべき追加事項が存在する。

  • DOMとそれを効果的に操作すること。つまり、追加、削除、ノードの変更だ。テキストノードも同様。
  • Document fragmentのようなツールを使って、ブラウザの再走査(re-flow)を最小限にすることを含む。
  • クロスブラウザに対応した方法でDOMから情報を抽出すること(例:style、positionなど)。このようなことは、jQueryやDojoなどのフレームワークで非常にうまくなされているが、CSS対styleタグに代表されるような情報を抽出することと位置やサイズを指定することの違いを理解することが重要だ。
  • クロスブラウザ対応でイベントをハンドリング、バインディング、アンバインディング、バブリング、つまり、望みのコールバックコンテキストを達成する方法。重ねて言うが、これはフレームワーク経由であれば、非常にうまくハンドリングされているが、個人でもIEとW3C標準のブラウザとの違いを理解するべきだ。
  • Expando対attribute設定とそれらのパフォーマンスが違い、名称との不一致(naming discrepancies)があるということ。
  • DOMノードを抽出する正規表現
  • ブラウザの機能を効果的に検出して、それらを上品に剥奪すること(graceful degradation)。

上記のリストからわかることは、JavaScriptには、alert(myVal)やmyBtn.onclick = ...以上のものがたくさんあるという地獄が存在するということだ。コピペできる以上のことがかなり多く存在するし、書籍を読み訓練することでしか本物のJavaScriptプログラマになることことはできない。これらすべてのトピックをカバーする偉大な書籍が『JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス』と『Secrets of the JavaScript Ninja』だ。思い出してほしい。JavaScriptが最もアクセスしやすい言語で、誰もがブラウザを持っていて、セットアップの時間すらかからないということを。シンプルなHTMLページを作って、上に挙げた概念(concepts)と戯れ始めよう。履歴書の脚色についてだが、初心者レベルをカバーして、中級レベルに飛び込んでいれば、JavaScriptをリストに加えてもよいと認めよう。コピペしないで、自分が望んだ機能(function)を開発していることに気づいたなら、JavaScriptを知っていると主張できる。それまではJavaScriptを知っているなどと宣伝しないでほしい。

私が書き損じたJavaScriptの側面があれば、コメントから知らせてほしい。また、JSや他の言語を知っていると主張する人に出会った経験を共有してほしい。

付け加えておくと、私はフロントエンド開発者ではなく、バックエンド開発者であり、フルスタック開発者へと進化してきた。今日では、ほとんどすべてのバックエンド開発者はJavaScriptを学ぶ必要があり、それがこの記事の意図するところだ。見下そうという意図はなく、JSにあるものすべてを知れと主張するわけではない。私の希望は、JavaScriptは広大でパワフルな言語で、見た目以上のものがあるのだと、より多くの人が気づいてほしいということだ。

もし、このポストを気に入ったらTwitterで私をフォローしてほしい。

*1:2011/11/19追記 以下も参考にしてください。Togetter:arguments.calleeがstrictモードで禁止な理由

なすなす 2011/11/17 11:01 基本レベルの1つめの「jfステートメント」ってのはifの間違いではありませんか;

teramakoteramako 2011/11/17 12:02 「JavaScriptの理解の上級レベル」部分:
うまい日本語訳は分かりませんが、『具体的な状況が思い浮かばず』と書かれていたので補足として。

"how it can be used to overload functions through arguments.length ..."

Javaなどの言語だと同名のメソッドで別の引数の数や型を受け付けるメソッドを定義するのをoverloadと言いますが、これを表現するためにoverloadという言葉が使われているのだと思います。

function foo(a,b){
var args = [];
for (var i = 0; i < arguments.length; ++i) {
args.push(arguments[i]);
}
}

fooという関数宣言では引数a,bの二つを設定していますが、JavaScriptでは引数の数や型は何でもOKですので、foo(1,2) は当然ながら、foo(1,2,3,4,5,6) の様な事もできます。
arguments変数には a, bに入る値以外にも全ての値が入っている(arguments.length個)ので、一つのメソッドでさまざまな引数の数に対応できるということを言いたい文だと思います。



また、"It should be noted that 〜" 部分ですが「〜を記しておかなければならないだろう。⇒〜を記しておこう。」の意として取りましたが、どうでしょうか。

suginoysuginoy 2011/11/17 12:41 >なすさん
typoでした。ありがとうございます。

>teramakoさん
解説ありがとうございます。
なるほどよくわかりました。
shouldもid:teramakoさんので正しいと思います。