在对象方法上使用它会返回错误

时间:2016-09-12 16:07:13

标签: javascript jquery this

我觉得我对this的全部理解已被抛到空中。

我有一个Quiz对象,其中包含播放测验所需的必要变量和方法。

我正在尝试从测验中的另一种方法(getQuestion中的skipQuestion())引用测验方法但是,我在控制台中看到一条消息说this.getQuestion未定义。我的印象是this在这种情况下引用它所在的对象,因此有问题的函数应该被称为this.getQuestion()

我收到的错误消息是script.js:18 Uncaught TypeError: this.getQuestion is not a function

有谁能解释这里出了什么问题?

在我的init函数中,this似乎引用了Quiz对象,但在skip question中它似乎发生了变化。这是查询具有不同的this定义吗?你在哪里画线,什么时候this的上下文改变了?

(function(window){

    $(document).ready(function(){
        var Quiz = {

            score : 0,
            question: '',
            answer: '',

            init: function() {
                this.getQuestion();
                this.checkAnswer();
                this.skipQuestion();
            },

            skipQuestion: function() {
                $('#skip').click(function(){
                    this.getQuestion();

                })
            },

            getQuestion: function() {
                $.get('http://jservice.io/api/random', function(data){
                    $('#question').html(data[0].question);
                    this.answer = data[0].answer.toLowerCase();
                });
            },

            checkAnswer: function() {
                if($('#answer').val() === this.answer) {
                    this.score += 1;
                }
            }
        }

        Quiz.init();
    });

})(window);

2 个答案:

答案 0 :(得分:1)

因为您在另一个函数中嵌套,this上下文将更改为该函数,因此您查找的方法不再可用。您可以尝试通过将this存储在将在您定义的函数范围内的变量中来解决它,或者使用双箭头函数(它们本身没有关联的this上下文)(因此也不支持bindcall)。您可以选择以下选项:

声明变量:

skipQuestion: function() {
    var that = this;
    $('#skip').click(function(){
        that.getQuestion();
    })
}

双箭头功能

skipQuestion: function() {
    var that = this;
    $('#skip').click(() =>  that.getQuestion())
}

你的init函数被认为是你的Quiz对象的方法,而传递给click事件的 anonymous 函数是不是的方法您的测验,它是在后台创建的匿名对象的方法,并且不与您的测验共享任何方法或变量。这一点很重要!

答案 1 :(得分:0)

问题是你在click事件中使用this并且它引用的是事件而不是你的上下文。要解决此问题,您需要将其分配给另一个变量,然后使用它;

      skipQuestion: function() {
            var self = this;
            $('#skip').click(function(){
                self.getQuestion();

            })
        },

$.get.click事件创建了自己的上下文,因此this引用了它们的上下文而不是测验的上下文。

<强> JS

(function(window){

    $(document).ready(function(){
        var Quiz = {

            score : 0,
            question: '',
            answer: '',

            init: function() {
                this.getQuestion();
                this.checkAnswer();
                this.skipQuestion();
            },

            skipQuestion: function() {
                var self = this;
                $('#skip').click(function(){
                    that.getQuestion();

                })
            },

            getQuestion: function() {
                var self = this;
                $.get('http://jservice.io/api/random', function(data){
                    $('#question').html(data[0].question);
                    self.answer = data[0].answer.toLowerCase();
                });
            },

            checkAnswer: function() {
                if($('#answer').val() === this.answer) {
                    this.score += 1;
                }
            }
        }

        Quiz.init();
    });

})(window);