Распространение * this * в вызовах вложенных функций в Backbone.js - PullRequest
3 голосов
/ 06 августа 2011

Я недавно начал использовать backbone.js для игры. Я использовал модель для создания таймера следующим образом:

var Timer = Backbone.Model.extend({
    defaults: {
        'hh':00, 'mm':05, 'ss':00
    },

    initialize: function() {
    },

    countDownOnce: function() {
         // Count down the time by 1 sec
    },

    run1: function() {
        this.countDownOnce();
    }

    run2: function() {  
        setInterval(this.countDownOnce, 1000);  
    }  
});

Функция countDownOnce , если вызывается напрямую, как в run1 , работает нормально.

Но если функция передается в качестве аргумента какой-либо встроенной функции, скажем, setInterval, как в функции run2 , значение this теряется.

Как распространить этот указатель на встроенные функции?

Ответы [ 3 ]

2 голосов
/ 08 августа 2011

В документах Backbone есть полезный раздел, посвященный привязке "this" .

По сути, Underscore предоставляет несколько очень полезных функций, _. Bind и _.bindAll , которые помогают вам легче управлять этим контекстом.

...

initialize: function() {
  _.bindAll(this, 'countDownOnce' //, and whatever other functions you want bound)
}),

...

Это гарантирует, что независимо от контекста, из которого он вызывается, «this» внутри countDownOnce ссылается на ваш экземпляр Timer.

1 голос
/ 06 августа 2011

это - это то, как был разработан javascript (каламбур предназначен:)

По сути, «this» привязывается к текущему контексту, поэтому при вызове функции / метода, например:

var Data = function(name) {
   this.name = name;
}

var myData = new Data("viky");

будет ссылаться на элемент имени «внутри» данных (т. Е. MyData в данном случае)

Теперь, если у вас есть следующее:

var Data = function(name) {

function morphName(anotherName) {
  //and if you call this like this ;)
   alert(this.name); //undefined
  }

}

внутренняя функция morphName имеет видпривязан к «текущему» контексту, т. е. внешней функции.В javascript все является объектом, включая функции.Поэтому внешняя (анонимная) функция не имеет члена с именем name!(имеет смысл?)

Чтобы сделать , что большинство людей использует следующее (по соглашению):

var Data = function(name) {

var that = this; //capture current context. Some prefer self = this;

function morphName(anotherName) {
  //then you access name like that ;)
   alert(that.name);
  }

}

Я предлагаю вам прочитать о замыканиях и областях javascriptчтобы понять то и это: D

1 голос
/ 06 августа 2011

Один из способов сделать это - использовать call и применить . Например:

run2: function() {  
    setInterval(this.countDownOnce.call, 1000, this);  
}

Также обратите внимание, что для передачи ссылки на замыкание / функцию с аргументами в setTimeout() и setInterval() требуются некоторые ручные хаки для корректной работы в IE.

...