Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   this не в контексте объекта (https://javascript.ru/forum/misc/62441-ne-v-kontekste-obekta.html)

woojin 11.04.2016 10:49

this не в контексте объекта
 
есть такой объект:
var answerTimer = {
    this: answerTimer,
    timerAnswer: -1,
    answerTimerId: null,
    timer: function () {
        ++this.timerAnswer;
        this.toPrint();
        this.answerTimerId = setTimeout(this.timer, 1000);
    },
    reset: function () {
        this.timerAnswer = 0;
    },
    stop: function () {
        this.reset();
        clearTimeout(this.answerTimerId);
    },
    toPrint: function () {
        document.getElementById("answerTimer").innerHTML = "last answer: " + this.timerAnswer + " sec";
    },
};

при вызове setTimeout из первой функции, в this оказывается контекст window!
как сделать что бы this был в контекст самого объекта?

nerv_ 11.04.2016 11:05

setTimeout(this.timer.bind(this), 1000);

woojin 11.04.2016 11:12

спасибо!

а, автоматизировать эту "биндовку" ни как нельзя?
к примеру добавить функцию которая при создании объекта сама сразу привязывала все методы и переменные к данному объекту?

рони 11.04.2016 11:22

woojin,
<div id="timer"></div>
 <script>
 var answerTimer = {
    timerAnswer: 0,
    answerTimerId: null,
    timer: function () {
        this.toPrint();
        ++this.timerAnswer;
        var self = this;
        this.answerTimerId = setTimeout(function() {
        self.timer()
}, 1000);
    },
    reset: function () {
        this.timerAnswer = 0;
    },
    stop: function () {
        this.reset();
        clearTimeout(this.answerTimerId);
    },
    toPrint: function () {
        document.getElementById("timer").innerHTML = "last answer: " + this.timerAnswer + " sec";
    }
};
  answerTimer.timer();
  setTimeout(function() {
        answerTimer.stop()
}, 5054);

  </script>

ruslan_mart 11.04.2016 12:44

(function(window) {
    var setTimeout = window.setTimeout;
    window.setTimeout = function(callback, delay, context) {
         setTimeout(callback.bind(context), delay);
    };
})(window);
/***********************/



var obj = {
    fn: function() {
        alert(this.foo);
    },
    foo: 'bar'
};

setTimeout(obj.fn, 1000, obj);

nerv_ 11.04.2016 13:52

woojin, правильный вариант того, что ты хочешь сделать, выглядит как-то так

function Timer(selector) {
  this.id = null;
  this.element = document.querySelector(selector);
  this.tick = this.tick.bind(this);
  this.reset();
}

Timer.prototype.start = function() {
  this.reset();
  this.id = setTimeout(this.tick, 1000);
};
Timer.prototype.tick = function() {
  this.print();
};
Timer.prototype.reset = function () {
  this.timestamp = Date.now();
};
Timer.prototype.stop = function () {
  this.reset();
  clearTimeout(this.this.id);
};
Timer.prototype.print = function () {
  var diff = Date.now() - this.timestamp; // ms
  var seconds = Math.ceil(diff / 1000);
  this.element.innerHTML = "last answer: " + seconds + " sec";
};

// usage

var timer = new Timer("#answerTimer");
timer.start();

woojin 16.04.2016 12:16

это самый интересный вариант - спасибо!

P.S. вопрос не по теме: а как тогда JQ активируется без привязки к какому либо селектору?

orionpro 20.04.2016 17:10

Я вот не пойму, это типа такой приём используется ,чтобы показать, когда был написан комментарий или сообщение отправлено?


Часовой пояс GMT +3, время: 21:02.