Подтвердить что ты не робот

Как передать контекст анонимной функции?

Есть некоторая функция, которая делает что-то долгое работа и обеспечивает обратный вызов.

someFunc: function(argument, callback, context) {
  // do something long

  // call callback function
  callback(context);
}

В приложении я использую эту функцию

someFunc('bla-bla', function (context) {
  // do something with this scope
  context.anotherFunc();
}, this);

Как реализовать функцию обратного вызова без прохождения параметра context?

Вам нужно что-то вроде этого:

someFunc('bla-bla', function () {
  // do something with this scope
  this.anotherFunc();
}, this);
4b9b3361

Ответ 1

Принятый ответ кажется несколько устаревшим. Предполагая, что вы работаете в относительно современном браузере, вы можете использовать Function.prototype.bind в ванильный javascript. В качестве альтернативы, если вы используете underscore или jQuery, вы можете использовать _.bind или $.proxy соответственно (что при необходимости будет возвращаться к call/apply).

Вот простая демонстрация этих трех вариантов:

// simple function that takes another function
// as its parameter and then executes it.
function execute_param(func) {
    func();
}

// dummy object. providing an alternative context.
obj = {};
obj.data = 10;

// no context provided
// outputs 'Window'
execute_param(function(){
    console.log(this);
});

// context provided by js - Function.prototype.bind
// src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// outputs 'Object { data=10 }''
execute_param(function(){
    console.log(this);
}.bind(obj));

// context provided by underscore - _.bind
// src: http://underscorejs.org/#bind
// outputs 'Object { data=10 }'
execute_param(_.bind(function(){
    console.log(this);
},obj));

// context provided by jQuery - $.proxy
// src: http://api.jquery.com/jQuery.proxy/
// outputs 'Object { data=10 }'
execute_param($.proxy(function(){
    console.log(this);
},obj));

Здесь вы можете найти код в jsfiddle: http://jsfiddle.net/yMm6t/1/ (обратите внимание: убедитесь, что консоль разработчика открыта, или вы выиграли ' t видеть любой выход)

Ответ 2

Используйте Function.prototype.call для вызова функции и вручную установите значение this для этой функции.

someFunc: function(argument, callback, context) {
    callback.call(context); // call the callback and manually set the 'this'
}

Теперь ваш обратный вызов имеет ожидаемое значение this.

someFunc('bla-bla', function () {
  // now 'this' is what you'd expect
    this.anotherFunc();
}, this);

Конечно, вы можете передавать аргументы, как обычно, в вызове .call.

callback.call(context, argument);