2016-09-19 5 views
0

すべての配列でいくつかの機能を利用できるようにしたいと思います。例えばnode.jsのArray.prototypeを変更してください

、私は重複を除去する機能が欲しい:

Array.prototype.uniq = function() { 
    return Array.from(new Set(this)); 
}; 

しかし、私は私の全体のnode.jsのプロジェクトでは、この機能の作品を作りたいです。

npm startと入力したときに実行されるserver.jsに入力しても問題はありませんか?

クライアント上でも動作するとうれしいでしょう。それは可能なのですか、またはサーバーとクライアントが厳密に分離されていると考えるべきですか?

Array.prototypeをこのように拡張するのは悪い習慣ですか?私はちょうどコードを何度も書くのは馬鹿だと思う。

もう一つのオプションは

function uniquify(arr) { 
    return Array.from(new Set(arr)); 
} 

しかしarray.uniq()uniquify(array)よりも優れているようだ使用することができます。

+0

コードレビューの方が良いでしょうか? – Neal

答えて

0

であり、配列プロトタイプを操作するには「悪い習慣」と考えられます。

私は(個人的に)非常に「ユニーク」な名前を持つものではないとは思わないが、ユニークな名前は来にくい。

あなたが望むときに呼び出すことができ、使用できるユーティリティ機能を持つ方がはるかに優れています。

+1

推論なしに「悪い練習」と呼ぶことはできません。特にこれが彼女自身のプログラムであれば、彼/彼女は自分のニーズに合ったドメインをモデル化するのが理にかなっています。問題のコードが自分のプロジェクトに含めるように他の人に配布するように設計されている場合、ネイティブプロトタイプを操作するのは些細なこと(つまり「悪い」)だと思います。より適切な推論のための@ TJCrowderの答えを見てください。 – naomik

+0

「eval is evil」のようなものです。確かに、あなたが 'eval'を理解していなければ、あなたはそれを悪用し、問題のヒープを歓迎するでしょう。しかし、それは、その使用がいくつかの異なるシナリオで保証されているわけではありません。 – naomik

+0

鉱山とTJの回答は基本的に同じですが、他の回答にはより多くの単語があります。 ;-) – Neal

3

まず:あなたはArray.prototypeにプロパティを追加しようとしている場合は、んではないは、単純な代入を経由して、それらを追加します。これにより、列挙可能なプロパティが作成され、デフォルトで列挙可能なプロパティを持たない配列に依存するコードが破損します。

ので、代わりにdefinePropertyを使用します。ご質問

Object.defineProperty(Array.prototype, "uniq", { 
    value: function uniq() { 
     return Array.from(new Set(this)); 
    } 
}); 

を:私はちょうど私がnpm start入力したときに実行されるserver.jsに入れた場合

それは動作しますか?

私はあなたが何を言ってるのかserver.jsわからないんだけど、あなたは、内蔵されているノードの一部のファイルやnpmではなく、プロジェクトの一部を変更する話をしている場合、私は強くないをお勧めしますそう、です。

クライアントでも機能するとうれしいです。それは可能なのですか、またはサーバーとクライアントが厳密に分離されていると考えるべきですか?

これらは完全に別です。クライアントでこれを行う場合は、uniqをクライアントに追加するスクリプトを含める必要があります。

Array.prototypeをこのように拡張するのは悪い習慣ですか?私はちょうどコードを何度も書くのは馬鹿だと思う。

その上の思考の二つの陣営があります

  1. はい、それは悪いです。他の誰かと自分の名前を付けて、別の名前を付けて競合する可能性があります。uniq複数のソースからのコードを組み合わせることは非常に一般的になり、それらの問題の確率を高めます。将来のバージョンの言語にはuniqが追加されることがあります。委員会が言語を操作する(TC-39)ので、潜在的な競合を回避しようとしているので、クライアント側のライブラリが普及すれば、その作業はより困難になります。 (MooToolsは複数回あります。)

  2. いいえ、それは何のプロトタイプでもありません。名前の競合は、いつでもいつでも処理できます。 TC-39はそれを一掃できます。

あなたはそれを行うかどうかについて独自の決定を下す必要があります。

+0

+このクールな答えです。たとえば、オブジェクトに何かを追加するとします。'Object.prototype.compare = func ...'のようなjQueryを破棄し、あなたの髪を引っ張るようにします:)まだ...これはあなたがデフォルトのプロパティを変更するのを避けるべきではありません。この回答に示唆されているようにしてください。 – Redu

1

別のオプションは、グローバルな名前空間を汚染しない間は、あなたの拡張newArrayクラスに好きな方法で追加することができます

...あなたは両方の長所を得ることができるように配列クラスを拡張することです。

ブラウザでは、同じことをしなければなりませんが、ES6からES5に移行しているかどうか、自分自身をES6ブラウザに限定しているか、物事を作る方法を探しているかによって異なりますES5でも働きます。

newArray型を返すためのファクトリ関数を使用する方法があります。追加するメソッドがすべて反復可能でないように注意してください。

Extending Array with ES6 classes

+0

良いアイデア。しかし、あなたは本当にこのためのクラスを必要としません。 [配列サブクラス化](https://www.quora.com/What-is-the-array-inheritance-problem-and-why-is-it-so-hard-to-solve/answer/%C3% 96mer-Ka%C5%9Fdarma?srid = 01By)は、ES6で、あるいはES5でも、Object.setPrototypeOf'または '__proto__'を利用して行うことができます – Redu

0

あなたはあなたのようなファイルを作成することができ、アプリケーション内で複数回使用する方法のような種類の場合:

appUtilsを

ここでの議論があります。 JS

var appUtils = {}; 

appUtils.getUniqueArray = function() { 
    return Array.from(new Set(this)); 
}; 

// can add other methods as well 

、あなたはこのFを使いたいところはどこでもあなたはこのファイルを必要とすることができます統一。他の再利用可能なメソッドがある場合は、上記のように追加することもできます。

関連する問題