JavaScriptで関数をコピー/クローンできますか?
-
22-07-2019 - |
質問
バリデータプラグインでjQueryを使用しています。 <!> quot; required <!> quot;を置き換えたい私自身のバリデーター。これは簡単です:
jQuery.validator.addMethod("required", function(value, element, param) {
return myRequired(value, element, param);
}, jQuery.validator.messages.required);
これまでのところ、とても良い。これはうまく機能します。しかし、私が本当にしたいことは、場合によっては自分の関数を呼び出し、残りはデフォルトのバリデーターにすることです。残念ながら、これは再帰的であることがわかりました。
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods.required(value, element, param);
}, jQuery.validator.messages.required);
バリデータのソースコードと、<!> quot; required <!> quotのデフォルト実装を確認しました。 jQuery.validator.messages.requiredで匿名メソッドとして定義されています。そのため、使用できる関数への他の(匿名ではない)参照はありません。
addMethodを呼び出す前に関数への参照を外部に保存し、その参照を介してデフォルトのバリデーターを呼び出す場合、違いはありません。
本当に必要なのは、参照ではなく値でデフォルトの必須バリデーター関数をコピーできるようにすることです。しかし、かなりの時間をかけて検索した後、その方法がわかりません。可能ですか?
不可能な場合は、元の関数のソースをコピーできます。しかし、それはメンテナンスの問題を引き起こします。<!> quot; better way。<!> quot;
がなければ、私はそれをやめたいです。解決
関数への参照を保存する addMethodを呼び出す前の外部 経由でデフォルトのバリデーターを呼び出す その参照は違いはありません。
それがまさに動作するはずです。
jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods.oldRequired(value, element, param);
}, jQuery.validator.messages.required);
これも動作するはずです:(そしてthis
の問題は解決されました)
var oldRequired = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return oldRequired.call(this, value, element, param);
// return jQuery.oldRequired.apply(this, arguments);
}, jQuery.validator.messages.required);
他のヒント
Function.prototype.clone = function() {
var fct = this;
var clone = function() {
return fct.apply(this, arguments);
};
clone.prototype = fct.prototype;
for (property in fct) {
if (fct.hasOwnProperty(property) && property !== 'prototype') {
clone[property] = fct[property];
}
}
return clone;
};
唯一の悪い点は、プロトタイプが複製されていないため、実際に変更できないことです... 私はあらゆる種類のオブジェクトのクローンを作成する方法に取り組んでおり、RegExpを行うだけです。 ですから、明日編集してコード全体を配置するでしょう(これは長くて、関数とオブジェクトにのみ使用する場合は最適化されません。
他の答えをコメントするには、eval()の使用はまったく馬鹿げており、長すぎるため、Functionコンストラクターも同じです。リテラルははるかに優れています。 また、そのためのJQueryを含めるだけでなく、適切に機能しない(そして機能しないと思う)ことは、あなたができる最も明るいことではありません。
更新された回答はこちら
var newFunc = oldFunc.bind({}); //clones the function with '{}' acting as it's new 'this' parameter
ただし、.bindはJavaScriptの新機能ですが、Mdnによる回避策があります
https://developer.mozilla.org/en/JavaScript/ Reference / Global_Objects / Function / bind
さらに、関数の追加プロパティを複製しません。
注: @gsnedderが指摘したように、バインドされたステートメント<!> quot; this <!> quot;引数uが指定されました(上記の空白{})。 apply()/ call()関数によるオーバーライドに関係なく、関数の将来の呼び出しに対して持続します。
これは、対処方法に応じて、利点と欠点の両方に使用できます。
あなたは、ちょっとしたスコーピングを見逃していると思います。これを試してください:
jQuery.validator.methods._required = jQuery.validator.methods.required;
jQuery.validator.addMethod("required", function(value, element, param) {
// handle comboboxes with empty guids
if (someTest(element)) {
return myRequired(value, element, param);
}
return jQuery.validator.methods._required.call(this, value, element, param);
}, jQuery.validator.messages.required);
(これは、のコメントのみにする必要がありますJavaScriptで関数をコピー/クローンしますか ...残念ながらrep <!> lt; 50は投稿のみ可能です
Function.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
十分、またはさらに
Object.prototype.clone=function(){
return eval( '('+this.toString()+')' );
}
効率に関する考え:
- 人間の効率は、人間を浪費するよりもはるかに重要です マシンの<!> quot; life <!> quot; を最適化または改善するためのリソース
- コンピューターと自動化システムは、人間の労力を減らすことになっています 増加させない
- 計算のオーバーヘッドは、結果の嗜好性に大きな影響を与える必要があります 多くの人々による人間の消費のために、投資を正当化するために コードを最適化する努力は、多くの場合、より不明瞭で不可解で、 非常に難解なので、stable舎ではもはや理解できない <!> quot;理解<!> quot;ロジック
クローン作成時:この質問はかなり修辞的です
- <!> quot; clone <!> quot;とはどういう意味ですか? javascriptオブジェクト?特に再帰関数理論の文脈で
- クローニングを合理化する共通のテーマは、それが分離され、<!> quot; protects <!> quot; doppelg <!>#228; ngerの変更からの発信者
-
a = new Object(); b = new Object();
がa
およびb
クローンの場合o = Object; a = new o(); b = new o();
はどうですか
- 本当に必要ですか?
- クローン作成はどこで停止しますか?プロトタイプの属性は
隔離されているため、これらのクローンオブジェクトの変更は影響しません
複製されたオブジェクトに関連付けられていないインスタンス?その場合
クローン作成は、プロトタイプチェーンから
それ自体が何らかの形である必要があるプリミティブコンストラクタ
クローンと分離(ブラウザでの1つのトリックは、新しいウィンドウを開いて、
opener .
などがクロス効果を漏らす可能性があるという警告を再入力することです)
関数のクローンを作成する場合は、これを試してください:
Function.prototype.clone=function(){
return eval('['+this.toString()+']')[0];
}
「より良い方法」はないように聞こえます。独自の必要な関数を作成してみてください。例:
jQuery.validator.addMethod("customRequired", function(value, element, param) {
return myRequired(value, element, param);
}, jQuery.validator.messages.required);
すでに他のすべてを試したことがあるように聞こえます。質問を誤解した場合はおologiesび申し上げます。
前の投稿に答え、コンストラクター関数を共有する必要があるとき、明確なプロトタイプを保持しながら、新しい関数でラッパーを使用します:
`
init_from_arg_obj = function () {
return new Function('init', 'for (var i in init) this[i] = init[i];');
};
constructor_A = init_from_arg_obj();
constructor_A.prototype = {a: 'A'};
constructor_B = init_from_arg_obj();
constructor_B.prototype = {b: 'B'};
`
いくつかのテストを実行して、これが優れたJSエンジンでの実行を遅くしないことを確認します。