21

バリデータプラグインでjQueryを使用しています。「必要な」バリデーターを自分のものに置き換えたいと思います。かんたんだよ:

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);

バリデーターのソース コードを調べたところ、"required" の既定の実装は、jQuery.validator.messages.required で匿名メソッドとして定義されています。したがって、私が使用できる関数への他の (匿名ではない) 参照はありません。

addMethod を呼び出す前に関数への参照を外部に保存し、その参照を介してデフォルトのバリデーターを呼び出すことには違いはありません。

私が本当に必要としているのは、デフォルトの必要なバリデーター関数を、参照ではなく値でコピーできるようにすることです。しかし、かなりの検索の後、私はそれを行う方法を理解できません。出来ますか?

それが不可能なら、元の関数のソースをコピーできます。しかし、それはメンテナンスの問題を引き起こします。「より良い方法」がない限り、私はそれをしたくありません。

4

8 に答える 8

18

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);
于 2009-01-15T17:42:35.620 に答える
9
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 を含めます。さらに、それが適切に機能しない場合 (そして私はそうは思わない) は、あなたができる最も明るいことではありません。

于 2010-03-29T20:20:05.177 に答える
5

これが更新された答えです

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が指摘したように:バインドされたステートメント、「this」引数uが提供されました(上記の空白の{})。apply()/ call()関数によるオーバーライドに関係なく、関数の今後の呼び出しに対して存続します。

これは、あなたの利点にも、あなたがそれをどのように扱うかに応じて不利にも使用することができます。

于 2011-07-21T07:30:42.643 に答える
4

(これはCan I copy/clone a function in JavaScript?のコメントのみである必要があります。残念ながら担当者が 50 未満の場合は投稿しかできません)

Function.prototype.clone=function(){
    return eval( '('+this.toString()+')' );
}

十分、または

Object.prototype.clone=function(){
    return eval( '('+this.toString()+')' );
}

効率に関する考え:

  • 人間の効率は、機械の「寿命」を最適化または改善するために人的資源を浪費するよりもはるかに重要です
  • コンピューターと自動化されたシステムは、人間の労力を増やすのではなく減らすと考えられています
  • 計算上のオーバーヘッドは、人間が消費するための結果の嗜好性に深刻な影響を与える必要があります。これは、コードを最適化するために投資する努力を正当化するものであり、コードはしばしば不明瞭で、難解で、非常に難解になり、何時間も試行した後に安定したプログラマーが理解できなくなります。ロジックを「理解する」

クローニングについて: この質問は非常に修辞的なものになる可能性があります

  • javascriptオブジェクトを「複製」するとはどういう意味ですか? 特に再帰関数理論の文脈では
    • クローニングを合理化するための共通のテーマは、それがドッペルゲンガーの変化からオリジネーターを隔離して「保護」することです。
    • とクローンの場合a = new Object(); b = new Object(); は?どうですかabo = Object; a = new o(); b = new o();
  • それは本当に必要ですか?
  • クローン作成はどこで停止しますか? 複製されたオブジェクトのこれらの変更が複製されたオブジェクトに関連付けられていないインスタンスに影響を与えないように、プロトタイプの属性も分離する必要がありますか? その場合、クローン作成はプロトタイプ チェーンをたどってプリミティブ コンストラクターに到達する必要があり、それ自体が何らかの形でクローン作成および分離される必要があります (ブラウザーでの 1 つのトリックは、新しいウィンドウを開いて、それを再読み込みすることですopener .。漏えい交差効果)
于 2014-03-18T21:53:02.740 に答える
4

私はあなたが少しスコープを欠いていると思います。これを試して:

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);
于 2009-01-15T17:58:38.800 に答える
2

関数を複製したい場合は、これを試してください:

Function.prototype.clone=function(){
    return eval('['+this.toString()+']')[0];
}
于 2009-02-11T22:20:31.840 に答える
1

「より良い方法」はないようです。独自のカスタム必須関数を作成してみることができると思います。

jQuery.validator.addMethod("customRequired", function(value, element, param) {
  return myRequired(value, element, param);
}, jQuery.validator.messages.required);

あなたはすでに他のすべてを試したようです。質問を誤解した場合はお詫び申し上げます。

于 2009-01-15T17:31:54.767 に答える
0

以前の投稿に答えて、コンストラクター関数を共有する必要がある場合、異なるプロトタイプを維持しながら、 new Function でラッパーを使用します。

`

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 エンジンでの実行を遅くしないことを確認します。

于 2009-06-09T19:32:24.857 に答える