函数外的全局变量返回undefined

时间:2012-11-24 17:49:35

标签: javascript global-variables

我尝试了一些不同的方法来避免从全局变量中获取未定义但是它会混淆代码的其余部分。我可以在所有函数中调用变量this.userHunger,但有几个。我知道我肯定在某个地方出了问题:

<html>
<head>
<script>
function user() 
{
    this.userHunger = 100;
    this.userHealth = 100;
    this.userFoodNumber = 10;

    this.checkForHungerHealthData = function() 
    {
        document.getElementById('userHealthDisplay').innerHTML = "Your Health:" + this.userHealth;
        document.getElementById('HungerBarVisual').innerHTML = "Your Hunger" + this.userHunger;
        document.getElementById('amountOfFood').innerHTML = "Amount of food" + this.userFoodNumber;
    }

    this.signInButton = function()
    {
        document.getElementById('myButtonSignIn').style.visibility="hidden";
        this.checkForHungerHealthData(); // displays current hunger and health
    }

    this.eatFood = function() 
    {
        if(this.userFoodNumber  > 0) 
        {
            this.userHealth = this.userHealth + 10;
            this.userHunger = this.userHunger + 50;
            this.userFoodNumber--;
            document.getElementById('amountOfFood').innerHTML = "Amount of food:" + this.userFoodNumber;
            document.getElementById('userHealthDisplay').innerHTML = "Your Health:" + this.userHealth;
            document.getElementById('HungerBarVisual').innerHTML = "Your Hunger is currently " + this.userHunger + "%";
        }
    }

    this.start=function()
    {
        this.hungerClockStart();
    }

    this.hungerClockStart=function()
    {
        this.setUserHungerClock(setInterval(this.updateHungerScreen,1000));
    }

    this.updateHungerScreen=function()
    {
        alert(this.userHunger); //Returns undefined
        if(this.userHunger >= 0) 
        {
            var subtractAmount=1;
            document.getElementById('HungerBarVisual').innerHTML = "Hunger is Currently at: " + this.userHunger + "%";
            this.userHunger--;
        }
    }
}

var user1 = new user();

</script>
</head>
<h1 id = "userHealthDisplay">Your Health:<br></h1>
<h1 id = "HungerBarVisual">Your Hunger:<br></h1>

<input id="myButtonSignIn" style="visibility:visible" type="button" value="Sign in" onclick="user1.signInButton(); user1.hungerClockStart()">

<body>
<h1 id = 'Notifyer1'><br></h1>
<h1 id = 'Notifyer2'><br></h1>
<h1 id = 'amountOfFood'>Amount of Food:</h1>
<input id="eatFoodButton" style="visibility:visible" type="button" value="Eat some food!" onclick="user1.eatFood()">

</body>
</html>

我在this.hungerScreenUpdate中一直收到错误,无法理解原因。

1 个答案:

答案 0 :(得分:2)

this.setUserHungerClock(setInterval(this.updateHungerScreen,1000));

需要

this.setUserHungerClock(setInterval(this.updateHungerScreen.bind(this),1000));

在JavaScript中,this是动态的,而不是词汇,因此this可以根据其调用方式而改变。当您执行setInterval(this.updateHungerScreen,1000)时,它不会使用正确的updateHungerScreen值来调用this。您可以使用bind将函数绑定到特定上下文。


正如评论者所建议的那样,如果你需要它在IE8及以下版本上工作,你需要在bind中进行填充,或者使用Phrogz的存储this作为变量的技术。


更新

有关this在JavaScript中的工作原理的概述,请参阅https://stackoverflow.com/a/13373383/1662998

就个人而言,我建议在bind中填写IE8及以下版本。这样,您可以继续使用新功能,同时保持与旧浏览器的向后兼容性。只需将其添加到页面顶部的脚本中,您就可以了:

if (!Function.prototype.bind)
    Function.prototype.bind = function(context/*, ...preArgs */) {

        var f = this,
            preArgs = Array.prototype.slice.call(arguments, 1);

        if (typeof f != 'function')
            throw new TypeError('Function expected.');

        if (context != null)
            context = Object(context);

        return function bound(/* ...args */) {
            var args = Array.prototype.slice.call(arguments);
            return f.apply(context, preArgs.concat(args));
        };

    };