JavaScript函数重新定义
是否可以从JavaScript函数本身的主体中重新定义JavaScript函数。例如,我可以执行以下操作吗JavaScript函数重新定义,javascript,Javascript,是否可以从JavaScript函数本身的主体中重新定义JavaScript函数。例如,我可以执行以下操作吗 function never_called_again(args) { // Do some stuff never_called_again = function (new_args) { // Do some new stuff } } 上述内容有效吗?其语义是否正确?我不想用旧函数名创建一个新的全局变量,因为我不想在全局范围内,而是从不同的对象范围内创建这种类型
function never_called_again(args) {
// Do some stuff
never_called_again = function (new_args) {
// Do some new stuff
}
}
上述内容有效吗?其语义是否正确?我不想用旧函数名创建一个新的全局变量,因为我不想在全局范围内,而是从不同的对象范围内创建这种类型的变量,而且我不希望在这些局部范围内重新定义函数时出现名称冲突。您的示例基本上与:
var never_called_again = function(args) {
//do some stuff
never_called_again = function (new_args) {
//do some new stuff
}
}
因为您可能知道这是可行的:
var a = 1;
function myFunction() {
//do some stuff
a = 2;
}
myFunction();
alert(a) //==> 2
很明显,第一个例子也适用
你是否真的想这样做是一个更开放的问题。这会使代码更难理解吗?是的,您可以用这种方式重新定义函数 运行此:
function never_called_again(args) {
console.log('Func 1', args);
never_called_again = function (new_args, x) {
console.log('Func 2', new_args, x);
}
}
never_called_again('arg A', 'arg B');
never_called_again('arg A', 'arg B');
结果如下:
Func 1 arg A
Func 2 arg A arg B
确实可以从函数体中重新定义函数。该技术用于所谓的中
// Conditional Module Pattern
var foo = (function() {
var t;
return function() {
if (t) {
return t;
}
t = new Date();
return t;
}
})();
看起来是这样的:
// Lazy Function Definition Pattern
var foo = function() {
var t = new Date();
foo = function() {
return t;
};
return foo();
}
此函数存储第一次调用的日期,然后返回此日期
如果将其与模块模式进行比较,区别在于初始化只在第一次调用时发生,而不是在定义时发生。对于成本高昂的初始化来说,这可能是一个巨大的好处
// Conditional Module Pattern
var foo = (function() {
var t;
return function() {
if (t) {
return t;
}
t = new Date();
return t;
}
})();
是的,这是可能的,它不会创建全局函数。我在InternetExplorer6、Firefox、Chrome和。 考虑下面的代码:
<head>
<title>Never called again</title>
<style type="text/css">
</style>
<script type="text/javascript">
function hello() {
function never_called_again(args) {
alert("Hello world " + never_called_again);
//do some stuff
never_called_again = function (new_args) {
//do some new stuff
alert("hello " + never_called_again);
}
}
never_called_again();
never_called_again();
}
</script>
</head>
<body onload="">
<button onclick="hello(); never_called_again();">Call</button>
</body>
再也没有打过电话
函数hello(){
函数永不再次调用(args){
警惕(“你好,世界”+再也不打电话了);
//做点什么
不再调用函数(新参数){
//做一些新的事情
警惕(“你好”+再也不打电话了);
}
}
再也不打电话了;
再也不打电话了;
}
呼叫
这将打印“Hello World{function code}”,第一次打印从未调用过的函数,第二次打印“Hello{changed function code}”
但是当在button的onclick上调用它时,它会抛出一个错误,表示函数未定义,清楚地表明函数已重新定义(且未全局创建)。完全可以在第一次调用时将函数对象重新定义为您想要的任何对象 之所以可能,是因为分配评估是从右向左处理的。这意味着在执行函数时(在本例中,在调用函数时)会捕获函数的范围 这实际上意味着在执行时,正在执行的函数对象和原始函数定义实际上是两个不同的东西,这也允许重新定义原始函数。。。什么都可以 使用它的最好(也是最酷的)方法之一是创建一个本质上是它自己的工厂的函数。通过这种方式,您不必携带大量不需要使用的对象定义 例如:
d = function(type){
switch(type.toUpperCase()){
case 'A' :
d = (
function(){
return {
name : 'A',
getName : function(){return this.name;}
};
}
)();
break;
case 'B' :
d = (
function(){
return {
name : 'B',
getName : function(){return this.name;}
};
}
)();
break;
default:
d = (
function(){
return {
name : 'DEFAULT',
getName : function(){return this.name;}
};
}
)();
break;
}
};
console.dir(d);
d('A');
console.dir(d);
console.log(d.getName());
严格地说,不,根本不可能重新定义JavaScript函数。虽然这是一个语义问题 一个函数可能会用另一个函数覆盖其在某个范围内的引用,当另一个函数出现在第一个函数的位置时,这是一种花招。e、 g
greet_once = function() {
console.log('Hello.');
greet_once = function() { console.log('Can I help you?') };
};
类似地,函数在第二次调用时可能会使用封闭范围的状态来表现不同的行为(显然不是“重新定义”)
下面的示例说明了为什么上面的模式没有重新定义,因为它依赖于父范围,而父范围可能不与调用范围共享
greet_always = function() {
greet_once = function() {
console.log('Hello.')
greet_once = function() { console.log('Can I help you?') }
};
return greet_once()
}()
greet_always()
greet_always()
被称为greet\u always
(总是打印“Hello.”)的函数与原来分配给greet\u once
的函数相同
我认为最接近重新定义函数的方法是重新分配其apply和call方法,这会产生一个场景,其中
myFunction.call()
不同于myFunction()
,这很奇怪,但可以想象是有用的。我不知道您是否可以,但这似乎不是一件好事。我显然不知道你的情况是什么,但这听起来很有可能造成混乱,难以追踪bug和难以阅读代码。我会认真思考这是否是正确的解决方案,或者你是否想后退一步,问一个让你找到答案的问题。抱歉,如果您已经考虑了所有选项。你永远不可能知道有人已经知道或不知道…这是一个合法的用途,这是一个强大的东西。人们害怕他们不知道的东西,但这并不意味着他们不好。请注意,这种技术实际上并没有重新定义函数,它改变了不再调用的函数。原始函数不一定会消失,因为(尽管您在这里没有这样做)可以创建另一个引用原始函数的变量:putoriginal=never\u called\u代码>在重新分配之前,不再调用
并且original()
将调用原始文件…感谢链接,这非常有趣,我正在以类似的方式使用该模式以避免各种条件执行路径。这应该是正确的答案。很高兴发现有一个名字是为这种做法创造的。@galambalazs:我给了你荣誉,并且我对你没有涵盖的方面进行了扩展,使我满意。此外,我的第一个答案和主要答案与你的答案无关,这已经足够了。它不是一个社区维基。全局变量与函数重新定义无关,它们只与Lazy Func相关。定义模式,其中