2012-03-24 9 views
1

インタビュアーは、私はjavascriptの "パターン"に従い、 "クリーンなコード"を書かなければならないと教えてくれました。彼はまた、プロトタイプパターンに従うべきだと言った。ここに私のコードのサンプルです:インタビューで私のJavaScriptコードが受け入れられなかったのはなぜですか?

//namespace declrations 
var MyNamespace = {}; 
MyNamespace.UCs = {}; 
MyNamespace.Pages = {}; 
//function declarations 
MyNamespace.UCs.test = function() { alert('this is a test function in user control namespace.'); } 
MyNamespace.Pages.test = function() { alert('this is a test function in web page namespace.'); } 

私はこのコードが大丈夫ではない理由を誰でも指摘できますか?つまり、最初に名前空間を宣言してから、上記のサンプルのようなメンバーと関数を追加しました。それは本当に問題があるのですか、何か不足していますか?

+4

これは実際にはコードレビューサイトにあるはずですが、代替サイトリストには記載されていません。 – Alnitak

+0

javascriptパターンの良い出典はこちらhttp://addyosmani.com/resources/essentialjsdesignpatterns/book/ –

+0

要求事項?インタビュアーの実際の要件がなければ、コードを判断することは非常に難しいです。私は彼があなたにオブジェクトリテラルの束を書くように依頼したのか疑問に思う。 – Esailija

答えて

4

あなたがコードを書いている:

第二に、あなたが名前空間を完全に制御を持っている場合も私はいくつかのカプセル化のために行くだろう、どこにでも実装プロトタイプ「パターン」を持っていません大規模な環境では、多くの問題が発生する可能性があります。したがって、クラス定義とそのクラスの使い方を区別することが重要です。これはまた、あなたが言うことを証明するために単体テストできるクラスを作る必要があることを意味します。 Javascriptは真のオブジェクト指向言語ではなく、それを「偽造」するいくつかの方法があります。しかし、言語には柔軟性があるため、いくつかのアプローチを複製することができます。

3つまたは4人の他のプログラマが、コードが何をしているのかを前提にして、意図しない "機能"を後で引き起こす可能性があるからです。グローバル変数が1つまたは2つの関数クロージャを上書きしたことがわからない場合は、その問題がより困難になることがわかります。だから私はJohn Resigで作成された小さなクラスを使用することをお勧めします。これは非常に簡単なアプローチであり、必要な機能をたくさん提供します。

コードを書きましょう。

[OK]をここではたくさんのものがあります。主要な部分は、これがクラスのすべての定義であるということです。私は実際には何も使用していません。プログラムは@staticで宣言されているLogEntry.PAGE_LOAD_STARTに現在の時刻のみを格納するので、動作は期待されます。私はここにたくさんのjsDocsを使用して、意図が何であるかをすべて明確にしました。 intelliJのようなプログラムは、あなたがそれらを文書化した方法でクラスを使用していない場合、コードフィードバックを与えるためにそれらを使用することができます。

このプログラムでは、ログデータを作成し、ログデータを保存することができます。これを行うための他の多くの方法があります。私はコンストラクタの中ではなく、コンストラクタの前にすべてを宣言して、型とそれらがプライベートであるかどうかを文書化することができます。

ログを使用しなければならないプログラマは、その使用方法を正確に知っていて、これらのクラスを作成または拡張したい場合は、関数クロージャによる意図しない影響を与えることなく行うことができます。

は、ここでそれを使用する方法は次のとおりです。もちろん

var anotherNamespace = anotherNamespace || {}; 

var anotherNamespace = new myNamespace.Log(); 

... 

anotherNamespace.log.msg("This is a test"); 

... 

anotherNamespace.log.data("Test msg with data", data); 

ここに欠けている明白なことは、すべてのデータを表示する方法です。しかし、それはLog.log配列を繰り返し処理し、toString()をWebページまたはファイルに吐き出す別のクラスにある可能性があります。ここでのポイントは、クラスとその関数がシンプルで、単体テスト可能であり、定義のみであることです。

+0

ありがとう。あなたのコードとコードIvo Wetzelの違いがたくさんあるので、どちらが標準であり、名前空間とクラスを定義するためのよりよい方法であるかわかりますか? – jim

+0

私の意見では、鉱山にはかなりの利点があります。最も明白なのは、私の例でクラスを拡張できるということです。ヴェッツェルが作った「すべての割り当て浪費線」についてのコメントは、それらの線のポイントを欠いています。可読性は常に最適化よりも優先されます。上記で書いたコードは、再利用可能で、拡張可能で、読みやすいです。すべてがソースコードの唯一の手ではないプロのソフトウェア開発において非常に重要です。 – CrazyBS

+0

ですが、次のステートメントはありません。var myNamespace.LogEntry = Class.extend({}); var myNamespace.LogEntry = function(){};次のようになります。およびvar myNamespace.DataEntry = myNamespace.LogEntry.extend({});実際には次のようになります。var myNamespace.LogEntry.prototype.DataEntry = new function(){}; – jim

0

インタビュアーは文字通り「名前空間」メソッドを使用する必要があることを意味しましたか?使い方の例と

チュートリアル: http://elegantcode.com/2011/01/26/basic-javascript-part-8-namespaces/

+0

彼がそれを意味するかどうかわからない、おそらく彼だった。ありがとう! – jim

+0

私は実際には、この行が "MyNamespace.UCs.test"であると思います。私は、雇用主が "MyNamespace.UCs.prototype.test"を希望していたと思います。 .prototypeを使用すると、C#などのlangaugesのクラス定義に近づく –

+0

@jim彼はそれが意味するようには聞こえませんが、結局は "標準的な"方法ではありません。 – Alnitak

0

あなたのコードの見た目(主に)罰金、目的はただのオブジェクト指向やデータのカプセル化せずに、共有名前空間でのユーティリティ関数を入れていた場合。

私は、最初の名前空間宣言の変更、作られています:コードは、それらの名前空間の任意の既存のメソッドを抹消していないことを確認するために

var MyNamespace = MyNamespace || {}; 
MyNamespace.UCs = MyNamespace.UCs || {}; 
MyNamespace.Pages = Mynamespace.Pages || {}; 

を。

+0

"目的は、オブジェクトの向きやデータのカプセル化なしに、共有名前空間にユーティリティ関数を置くことでした。"と私はexaclyオブジェクトの向きやデータのカプセル化をしたいのですが?どのように私のコードはそれに応じて変わるだろうか? – jim

+0

@jim if if 'MyNamespace.Pages.Counter = function(){...}' 'Counter 'は「クラス」で、あなたは' MyNamespace.Pages.Counter.prototype'に物を追加することでメソッドを追加できます。 – Alnitak

+0

nice!私はウェブサイトのjavascriptコードを集中化しようとしていました。 UCにはユーザーコントロールから呼び出される関数が含まれ、ページにはWebページから呼び出される関数が含まれます。 – jim

1

まず、オブジェクトリテラルを利用すると、それらの割り当てはすべて無駄な行になります。まあ

(function() { // anonymous wrapper 

    function Foo(a) { // i can haz prototype "Pattern" 
     this.memberVal = a; 
    } 

    Foo.prototype = { 

     someMethod: function(value) { 
      console.log(value, this.memberVal); 
     }, 

     yam: function() { 

     } 

    }; 

    // Let's assume we have full control here, otherwise Alnitak's answer is fine too. 
    window.namespace = { 

     test: { 
      Foo: Foo 
     } 

    }; 

})(); 

var test = new namespace.test.Foo(123); 
test.someMethod('bla'); 
+1

aha!私はインタビュアーが何を意味するのかを知ったと思います!これは少し複雑ではありませんか?面接者の期待が何であるかに依存する – jim

+0

。私の意見では、それは複雑ではない、それはそれが行われなければならない方法の一つです。答えのために –

関連する問題