假设我有var a = function() { return 1; }
. 是否可以更改a
以a()
返回2
?也许通过编辑a
对象的属性,因为每个函数都是一个对象?
更新:哇,谢谢大家的回复。但是,恐怕我并不想简单地重新分配变量,而是实际编辑现有函数。我正在考虑如何在 Scala 中组合部分函数来创建一个新的PartialFunction
. 我有兴趣在 Javascript 中编写类似的东西,并认为可能可以更新现有函数,而不是创建一个全新的Function
对象。
假设我有var a = function() { return 1; }
. 是否可以更改a
以a()
返回2
?也许通过编辑a
对象的属性,因为每个函数都是一个对象?
更新:哇,谢谢大家的回复。但是,恐怕我并不想简单地重新分配变量,而是实际编辑现有函数。我正在考虑如何在 Scala 中组合部分函数来创建一个新的PartialFunction
. 我有兴趣在 Javascript 中编写类似的东西,并认为可能可以更新现有函数,而不是创建一个全新的Function
对象。
你可以用 javascript 做各种有趣的事情,包括重新定义函数:
let a = function() { return 1; }
console.log(a()); // 1
// keep a reference
let old = a;
// redefine
a = function() {
// call the original function with any arguments specified, storing the result
const originalResult = old.apply(old, arguments);
// add one
return originalResult + 1;
};
console.log(a()); // 2
瞧。
编辑:更新以在更疯狂的场景中显示这一点:
let 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
您可以在此处看到,即使首先定义了“test”,然后我们重新定义了 substring(),更改仍然适用。
旁注:如果你这样做,你真的应该重新考虑你的架构......当她/他正在查看一个应该返回 1 的函数定义时,你会混淆一些糟糕的开发人员在 5 年后的废话,但似乎总是返回 2....
我使用类似这样的方法来修改我无法访问其声明的现有函数:
// 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>
);
您可能可以使用toString() 而不是 toSource()来获取包含函数声明的字符串。一些对 replace() 的调用以准备字符串以与函数构造函数一起使用并修改函数的源代码。
let a = function() { return 1; }
console.log(a()) // 1
a = function() { return 2; }
console.log(a()) // 2
从技术上讲,您正在丢失一个函数定义并用另一个函数定义替换它。
这个怎么样,无需重新定义函数:
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;
};
})();
console.log('a() ...', a()); // --> gives 2
.as-console-wrapper { min-height: 100%!important; top: 0; }
...并利用around
,代码将转换为 ...
function a () { return 1; }
console.log('original a ...', a);
console.log('a() ...', a()); // 1
a = a.around(function (proceed, handler, args) {
return (proceed() + 1);
});
console.log('\nmodified a ...', a);
console.log('a() ...', a()); // 2
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
(function(d){function f(a){return typeof a==e&&typeof a.call==e&&typeof a.apply==e}function g(a,b){b=null!=b&&b||null;var c=this;return f(a)&&f(c)&&function(){return a.call(b||null!=this&&this||null,c,a,arguments)}||c}var e=typeof d;Object.defineProperty(d.prototype,"around",{configurable:!0,writable:!0,value:g});Object.defineProperty(d,"around",{configurable:!0,writable:!0,value:function(a,b,c){return g.call(a,b,c)}})})(Function);
</script>
这是一个基于控制时间选择器的清晰示例eworld.ui
www.eworldui.net
拥有一个eworld.ui
无法从外部访问 JavaScript 的 TimePicker,您将找不到与这些控件相关的任何 js。那么如何向 timepicker 添加 onchange 事件呢?
当您在控件提供给您的所有选项之间有一段时间时,会调用一个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);
}
我已将 My Function 添加到函数中,因此现在我可以在选择时间时模拟 onchange 事件。
RaiseChange(...) 可以是任何你想要的。
如果您正在调试 javascript 并想查看代码更改如何影响页面,您可以使用此 Firefox 扩展程序来查看/更改 javascripts:
执行 JS firefox 扩展: https ://addons.mozilla.org/en-US/firefox/addon/1729
您可以像其他对象一样更改功能
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
const createFunction = function (defaultRealization) {
let realization = defaultRealization;
const youFunction = function (...args) {
return realization(...args);
};
youFunction.alterRealization = function (fn) {
realization = fn;
};
return youFunction;
}
const myFunction = createFunction(function () { return 1; });
console.log(myFunction()); // 1
myFunction.alterRealization(function () { return 2; });
console.log(myFunction()); // 2
绝对地。只需为其分配一个新功能。
你不能稍后再定义它吗?当您想要更改时,请尝试将其重新定义为:
a = function() { return 2; }