var a = function() { return 1; }
があるとしましょう。 a()
が2
を返すようにa
を変更することは可能ですか?おそらくa
オブジェクトのプロパティを編集することにより、 すべての関数はオブジェクトです ?
更新:すごい、すべての応答に感謝します。ただし、単に変数を再割り当てするのではなく、実際に既存の関数を編集するのではないかと心配しています。 部分関数 in Scala=を使用して新しいPartialFunction
を作成する方法について考えています。 Javascriptと、まったく新しいFunction
オブジェクトを作成するのではなく、既存の関数を更新できると考えていました。
次のようなものを使用して、宣言にアクセスできない既存の関数を変更しました。
// declare function foo
var foo = function (a) { alert(a); };
// modify function foo
foo = new Function (
"a",
foo.toSource()
.replace("alert(a)", "alert('function modified - ' + a)")
.replace(/^function[^{]+{/i,"") // remove everything up to and including the first curly bracket
.replace(/}[^}]*$/i, "") // remove last curly bracket and everything after<br>
);
ToSource()の代わりに、おそらく toString() を使用して、関数の宣言を含む文字列を取得できます。関数コンストラクタで使用する文字列を準備し、関数のソースを変更するためのreplace()の呼び出し。
JavaScriptを使用して、関数の再定義を含むあらゆる種類の楽しいことを行うことができます。
var a = function(){ return 1; }
alert(a()); //1
// keep a reference
var old = a;
// redefine
a = function(){
// call the original function with any arguments specified, storing the result
var originalResult = old.apply(old, arguments);
// add one
return originalResult + 1;
};
alert(a()); //2
出来上がり。
編集:クレイジーなシナリオでこれを表示するように更新されました。
var test = new String("123");
console.log(test.toString()); // logs 123
console.log(test.substring(0)); // logs 123
String.prototype.substring = function(){ return "hahanope"; }
console.log(test.substring(0)); // logs hahanope
ここでは、「テスト」が最初に定義され、その後substring()を再定義しても、変更が適用されることがわかります。
サイドノート:これを行う場合は、アーキテクチャを再検討する必要があります... 5年後のある貧しい開発者のがらくたを混乱させるでしょう。 、しかし常に2を返すようです...
var a = function() { return 1; }
alert(a()) // 1
a = function() { return 2; }
alert(a()) // 2
技術的には、ある関数定義を失い、別の関数定義に置き換えています。
そのため、既存の変数に別の関数を再割り当てするだけでなく、関数のコードをその場で直接変更したいと考えています。
私はそれを言うことを嫌いますが、私がそれを理解することができた限り-そして私が試みた-それは行うことができません。確かに、関数はオブジェクトなので、オブジェクト自体で調整および上書きできるメソッドとプロパティがあります。残念ながら、関数本体はそれらの1つではありません。パブリックプロパティには割り当てられません。
MDNのドキュメント は、関数オブジェクトのプロパティとメソッドをリストします。それらのどれも、外部から関数本体を操作する機会を与えません。
仕様による であるため、関数本体は関数オブジェクトの内部[[Code]]
プロパティに格納され、直接アクセスすることはできません。
関数を再定義する必要なく、これについてはどうですか:
var a = function() { return arguments.callee.value || 1; };
alert(a()); // => 1
a.value = 2;
alert(a()); // => 2
私はjvenemaのソリューションにこだわっています。このソリューションでは、グローバル変数「old」が好きではありません。古い関数を新しい関数内に保持する方が良いようです:
function a() { return 1; }
// redefine
a = (function(){
var _a = a;
return function() {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
}
})();
a() // --> gives 2
すべての実行可能なソリューションは、「関数ラッピングアプローチ」に固執します。 それらの中で最も信頼性の高いものは、rplantikoのものであるようです 。
このような関数のラッピングは簡単に抽象化できます。コンセプト/パターン自体は「メソッド修正」と呼ばれる場合があります。その実装は間違いなくFunction.prototype
に属します。 before
、after
、around
、afterThrowing
、およびafterFinally
などの標準的なプロトタイプメソッド修飾子によっていつかサポートされるといいでしょう。
Rplantikoによる前述の例は...
function a () { return 1; }
// redefine
a = (function () {
var _a = a;
return function () {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
};
})();
a(); // --> gives 2
... [around]
を使用すると、コードは...
function a () { return 1; }
console.log("a : ", a);
console.log("a() : ", a());
a = a.around(function (proceed, interceptor, args) {
return (proceed() + 1);
});
console.log("a : ", a);
console.log("a() : ", a());
他のオブジェクトのような機能を変更できます
var a1 = function(){return 1;}
var b1 = a1;
a1 = function(){
return b1() + 1;
};
console.log(a1()); // return 2
// OR:
function a2(){return 1;}
var b2 = a2;
a2 = function(){
return b2() + 1;
};
console.log(a2()); // return 2
これは明確な例制御タイムピッカーに基づいています_eworld.ui
_ www.eworldui.net
JavaScriptが外部から到達できないTimePicker _eworld.ui
_があるため、これらのコントロールに関連するjsは見つかりません。それでは、どのようにonchangeイベントをtimepickerに追加できますか?
コントロールが提供するすべてのオプションの間にjs
を挿入すると呼び出されるSelect
関数があります。この関数は:_TimePicker_Up_SelectTime
_
まず、この関数内のコードをコピーする必要があります。
評価... quikwatch ...TimePicker_Up_SelectTime.toString()
_function TimePicker_Up_SelectTime(tbName, lblName, divName, selTime, enableHide, postbackFunc, customFunc) {
document.getElementById(tbName).value = selTime;
if(lblName != '')
document.getElementById(lblName).innerHTML = selTime;
document.getElementById(divName).style.visibility = 'hidden';
if(enableHide)
TimePicker_Up_ShowHideDDL('visible');
if(customFunc != "")
eval(customFunc + "('" + selTime + "', '" + tbName + "');");
eval(postbackFunc + "();");
_
}
いま
同じソースコードを再割り当てする前に保存したコードを使用して、必要なものを追加します。
TimePicker_Up_SelectTime = function(tbName、lblName、divName、selTime、enableHide、postbackFunc、customFunc){document.getElementById(tbName).value = selTime; if(lblName!= '')document.getElementById(lblName).innerHTML = selTime; document.getElementById(divName).style.visibility = 'hidden'; if(enableHide)TimePicker_Up_ShowHideDDL( 'visible'); if(customFunc!= "")eval(customFunc + "( '" + selTime + "'、 '" + tbName + "');"); eval(postbackFunc + "();");
_ >>>>>>> My function >>>>> RaiseChange(tbName);
}
_
関数に関数を追加したので、時間を選択したときにonchangeイベントをシミュレートできるようになりました。
RaiseChange(...)は何でも構いません。
絶対に。新しい関数を割り当ててください。
後で定義し直すことはできませんか?変更が必要な場合は、次のように再定義してください。
a = function() { return 2; }
JavaScriptをデバッグしていて、コードの変更がページにどのように影響するかを確認したい場合は、このFirefox拡張機能を使用してJavaScriptを表示/変更できます。
JS firefox拡張機能を実行します: https://addons.mozilla.org/en-US/firefox/addon/1729