javascriptおよびMathオブジェクトでNumber.prototypeを拡張していますか?
-
05-07-2019 - |
質問
数字に独自のメソッドを与えるのではなく、JavascriptにグローバルなMathオブジェクトがあるのはなぜだろうといつも思っていました。それには正当な理由がありますか?
また、このようなことをすることには(効率以外の)欠点がありますか?:
Number.prototype.round = function(){
return Math.round(this);
};
明確にするために、π最小値/最大値などの複数の数値に適用される場所と関数が必要です。問題は主に、ラウンド、abs、sin、powなどの単一の数値のみに影響する方法に関するものでした。
解決
Math
オブジェクトの理由は簡単です:" because Java does it"。最良の理由ではありませんが、ここにあります。ダグラス・クロックフォードが言語の半分を抑圧するキャンペーンを開始する前に、当時はもっと理にかなっていたと思います*。もともと、あなたは「許可」されていたか、またはこのようなことをするつもりでした:
with (Math) {
var n = min( round(a) * round(b), sqrt(c) );
var result = exp( n + d );
}
Number.prototype
を拡張することの欠点は、他の誰かが同じことをする可能性があることです。さらに悪いことに、たとえば、 Number.prototype.round
を対称丸め関数として定義します。
あなたの人生をもっと楽にする方法を探しているなら、なぜそこで止まるのですか? Math
関数を単にグローバル関数として含めないのはなぜですか?
var m = 'abs acos asin atan atan2 ceil cos exp floor log max min ' +
'pow random round sin sqrt tan PI').split(' ');
for (var i=0,l=m.length; i<l; i++) {
window[ m[i] ] = Math[ m[i] ];
}
これにより、すべての数学関数がグローバルスコープにドロップされ、「数学」の入力を事実上停止できます。自問してください:これらの関数で Number
を拡張することと window
を拡張することの間に本当の違いはありますか?
*あなたが私に火をつける前に:Crockfordのコメントはあまりにも真剣に受け止められることを意図したものではありません。暗黙のグローバル環境では、 with
は非常に危険であることに同意します。
他のヒント
他の人を混乱させる以外に、 Number.prototype
を拡張しても欠点はありません。ポイントは何ですか? Math.round(value)
の代わりに value.round()
を使用する方が良いでしょうか?
Math
オブジェクトにはいくつかの正当な理由があります:
- 数値以外でも機能します:
Math.round(&quot; 5&quot;)
は機能しますが、value.round()
は値が文字列(たとえば、テキストボックスの値) - Mathオブジェクトの一部のメンバーは、「プライマリ」に属していません。
Math.min()
やMath.max()
などの数値。または、a.max(b)
のように使用しますか? - 他のメンバーはグローバルであり、特別な番号に属していません。例は、
Math.PI
や関数Math.random()
などの定数です。
123.round();
あなたのjavascriptコンソールは目に数百のエラーを投げます:P、nah ...
できること:
Number.prototype.x
then:(123).x();
ただし、 123.x();
MathはNumberメソッドのセット以上のものだと思います。それはより広い使用法です。たとえば、NumberVariable.PIを使用すると混乱する場合があります。乱数生成でも同じです。
また、JSの性質の一部であるため、番号を拡張しても問題ないと思います。私がここで間違っていれば、誰かが私を修正するかもしれません。
Numberのプロトタイプ関数は、他のすべてのObjectのプロトタイプ関数と同じように機能するため、このように呼び出すことも同様に機能すると考えています。
5.5["round"]();
//should return 6
だから、それが良いアイデアかどうかについての会話はさておき、あなたはこれをうまくやることができます。
123.x()を実行できますが、jsのインタープリターは壊れています(ドットをメッセージディスパッチとして解釈しないため)
奇妙なことに、代わりに123 .x()(数字とドットの間にスペースを入れて)を使用できます。これは動作します。
123 ..も機能しますが、これは事実上小数を作成してから小数にディスパッチしたためです
(typeof 123.)=== 'number')// true
試してください:
コンソールでNumber.prototype.times = function(other){return this * other}; 3 .times(5);
。
これに関する私の見解は、ネイティブの機能を上書きしないように適切なチェックを行うと、ネイティブの命名基準を理解して名前を付け、コードをより読みやすく管理しやすくし、コードを快適で便利にすることです。
if (Number.prototype.round == null)
Number.prototype.round = function() { return Math.round(this); }
これを使用するASは、javascriptの性質上、これを行う最良の方法は次のとおりであると考えています:
- 単純な静的値の代わりに変数で数値をラップする(ほとんどの場合)
- nNum.round();
- 単純な静的な値を括弧で囲む:
- (123).round();
- 角括弧表記を使用した呼び出し
- 123 [&quot; round&quot;]。call();
これを行うことができます
Number.prototype.round = function() {
return Math.round(this.valueOf());
};