以前是玩c# winform的,感觉“函数”肯定总是不变的才对但今天遇到个奇怪的问题,有没有高手从原理方面解释一下:为什么刚赋值时两个变量指向同一函数,过了一会就不指向同一函数了原代码有点长,我已经尽量从实际环境中把没用的东西都去掉了点两下checkbox,预期结果是两次提示true,结果第2次提示false
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<script>
var game = {action: null};
function setAction(b)
{
function doNothing()
{
} if (b)
{
game.action = doNothing;
alert(game.action == doNothing)
}
else
{
alert(game.action == doNothing); //返回false,太奇怪了
game.action = null;
}
}
</script>
<label for="chk">show time</label><input id="chk" type="checkbox" onchange="setAction(this.checked)"/>
</body>
</html>
<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<script>
var game = {action: null};
function setAction(b)
{
function doNothing()
{
} if (b)
{
game.action = doNothing;
alert(game.action == doNothing)
}
else
{
alert(game.action == doNothing); //返回false,太奇怪了
game.action = null;
}
}
</script>
<label for="chk">show time</label><input id="chk" type="checkbox" onchange="setAction(this.checked)"/>
</body>
</html>
function doNothing()
{
}
function setAction(b)
{
if (b)
{
game.action = doNothing;
alert(game.action == doNothing)
}
else
{
alert(game.action == doNothing); //返回false,太奇怪了
game.action = null;
}
}
函数doNothing()定义在函数setAction()内部,其作用域也在setAction()内部,
每当点击checkbox就会执行setAction(),而每当执行setAction(),
就是重新定义一个doNothing()。这个doNothing()虽然与之前的函数名函数体都一样,
但在内存中实际上是不同的。而game.action从第一点击checkbox开始,
以后每次点击,game.action就一直指向第一次点击定义的doNothing。所以,1楼将doNothing()的定义放在函数setAction()的外部,
这样,doNothing就不会被每次点击都重新定义了。
追问一下--- 照这样说,两个DoNothing函数的“实例”不同,我明白了。有没有办法识别它们是从同一处代码来的呢?比如利用prototype什么的... 有个保底的方法,转换成string比较函数体(除非有两个函数写的一样),有没有更直接的办法呢如果把DoNothing拿出来的话,函数容易重名,有很多麻烦。
var game = {action: null};
function setAction(b){
if(!setAction.doNothing){
setAction.doNothing = function(){
}
}
if (b){
game.action = setAction.doNothing;
alert(game.action == setAction.doNothing)
}else{
alert(game.action == setAction.doNothing); //返回false,太奇怪了
game.action = null;
}
}
定义在setAction外部,内部也可以吗?
的确是这样,您这个新的代码在函数
setAction开头每次点击都会检查
doNothing是否已经定义。
避免了楼主原始代码中每次都会重新定义
doNothing的做法。
doNothing放在setAction内或外不是关键,
避免doNothing重新定义才是关键。