僕はあまりブログを一生懸命書くのは嫌いです。で、いつも適当に言葉は少なめにソースだけで解説しているが。今回は、それだけでは伝わらないところまで突っ込まれてしまったので、僕が伝えたかった意図をこと細かく説明していこうと思います。
文章が苦手なので、変な言い回しで読み辛かったりすると思いますがよろしくお願いします。
一応、弾さんには断っておきますが、別に弾さんに噛みついている訳ではないです。ただ、弾さんのような有名人に突っ込まれたら、僕の講義を聞いてくれたエンジニアが嘘を教えられたと不安になってしまうのではないかと思ったのです。僕の講義を聞きにくれた人には、虚像でもいいから 100 % の自信と勇気を付けて欲しい(プログラムを書く上ではそれがとても大事だから)。
だから、あえて「反論」させていただきます。
# ブックマークのタグは「全力で反論」でお願いします。
僕は、弾さんの指摘していることを完全に理解したうえで正しいとは思わない。
しかも、弾さんが指摘していることは非常に細かなことで、まさに自転車置場の議論のようなものだ。プログラミングを学習している人はその細かなことで不安を煽られて欲しくない。
Object.prototype = {} は避けるべきではない*1
揚げ足を取るようで嫌なのだが、弾さんの以下の例では継承は行われない。
MyBox.prototype = Box.prototype;// ここで継承しているのに継承を行うなら、まず、継承を行えるように Box を書き換えて
var Box =function(){if (arguments.length == 0);// for extendselse{ : (本来のコンストラクタの処理) :}};
以下のようにプロトタイプを置き換えるべきだ。
MyBox.prototype =new Box;そして、これがJavaScript のプロトタイプ継承の正しい方法である。
MyBox.prototype =new Box;MyBox.prototype.hoge ='hoge';MyBox.prototype.fuga ='fuga';
ちなみに、弾さんがやるなと言っている
Box.prototype ={ hoge:'hoge', fuga:'fuga'};
のような書き方は、そもそも
Box.prototype =newObject;Box.prototype.hoge ='hoge';Box.prototype.fuga ='fuga';
のシンタックスシュガーに他ならない。
つまり、 Box.prototype = {...} という書き方は Object.prototype を正しく継承するための書き方に他ならないのである。
もし、そのシンタックスシュガーは癖になって継承のときにも使っちゃって継承が台無しになってしまうから使うな。という意味の指摘であれば、こう言わざるを得ない。「{} がnew Object; のシンタックスシュガーだということを理解していれば、そんな間違いを犯すことはないし、間違えてもすぐ気付くはずだ」。
もちろん、弾さんの書き方がダメと言ってる訳ではない。どちらも正しいので、趣味の問題、自転車置場の議論だと言っているのです。
たしかに弾さんのおっしゃるとおり、with は不思議な文法なので、あまり使うべきではないかもしれない。(ちなみに、僕は使ってもいいとは思ってる。)その件については社内勉強会でもかなり白熱した議論になった。
ただ、ここで言っておきたいのは、with 文の挙動を知らないと読めないソースがあるということだ。人のソースが読めるレベルの JavaScripter を育てるためにはwith 文の挙動は絶対に必要だ。
なぜなら、with 文はwith 文でしか説明できない現象であるからだ。オブジェクトのプロパティ名という名前空間を、スコープの変数名という名前空間に重ねる唯一の方法であるからだ。
そして、それを説明してwith 文を把握したうえで全員が納得した。そこにこそ、あそこでwith 文を紹介した意味があったのだ。
ただ、あの資料には、そのような説明書きがひとつもなかったのでこのような議論を生み出してしまったのだと思う。そこは、ひとこと(口頭ではなく)書き添えるべきだったかもしれない。
講義を聞いてくれたかたには「あの講義は微妙だった」とは思わずに、自信を持ってJavaScript を書いていって欲しいです。その過程でこの議論に自分なりの答えを見つけて欲しいです。
最後に弾さんに一言、偉そうなこと言ってごめんなさい><ごめんなさい><
*1:ma.la さんの指摘で直しました。混乱させてすみません
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。