简体   繁体   English

函数外的全局变量返回undefined

[英]Global Variable outside of function returning undefined

I have tried a bunch of different ways to avoid getting undefined from a global variable but it messes up the rest of the code. 我已经尝试了一些不同的方法来避免从全局变量中获取未定义,但它会混淆代码的其余部分。 I am able to call the variable this.userHunger in all functions but a few. 我可以在所有函数中调用变量this.userHunger,但有几个。 I know i must have gone wrong somewhere: 我知道我肯定在某个地方出了问题:

<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>

I keep getting an error inside the this.hungerScreenUpdate and cannot understand why. 我一直在this.hungerScreenUpdate中收到错误,无法理解原因。

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

needs to be 需要是

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

In JavaScript, this is dynamic, not lexical, so this can change depending on how it's called. 在JavaScript中, this是动态的,而不是词法,所以this可以根据它的调用方式而改变。 When you do setInterval(this.updateHungerScreen,1000) it doesn't call updateHungerScreen with the correct this value. 当您执行setInterval(this.updateHungerScreen,1000)它不会使用正确的this值调用updateHungerScreen You can use bind to bind a function to a specific context. 您可以使用bind将函数bind到特定上下文。


As the commenters have suggested, if you need it to work on IE8 and below, you need to either shim in bind or use Phrogz's technique of storing this as a variable. 由于评论者建议,如果你需要它的工作IE8及以下,你需要或者垫片在bind或使用存储Phrogz的技术this是一个变量。


Update 更新

For an overview of how this works in JavaScript, see https://stackoverflow.com/a/13373383/1662998 有关如何概述this工作在JavaScript中,看到https://stackoverflow.com/a/13373383/1662998

Personally, I recommend shimming in bind for IE8 and below. 就个人而言,我建议在IE8及以下版本中进行bind That way you get to go ahead and use new features while maintaining backwards compatibility with older browsers. 这样,您可以继续使用新功能,同时保持与旧浏览器的向后兼容性。 Just add this in a script at the top of your page, and you'll be good to go: 只需将其添加到页面顶部的脚本中,您就可以了:

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));
        };

    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM