2014-10-29 2 views
1

я сделал эту функцию в JavaScript:Есть ли способ получить этот/контекст из метода?

var syncCall = function(cb, obj, fn) { 
    var params = []; 
    for(var i=3; i< arguments.length; i++) { 
     params.push(arguments[i]); 
    } 
    fn.apply(obj, params) 
     .onReject(function(result){ 
     console.error(result); 
     }) 
     .onFulfill(function(result){ 
      if(cb != undefined && cb != null) { 
      cb(result); 
      } 
     }); 
}; 

Проблема заключается в том, что я должен obj проходит мимо параметров в syncCall function, to set proper context of это inside fn`, когда она вызывается.

В моем случае fn всегда является методом/функцией, которая хранится в одном из obj объектов. Поэтому обычно при выполнении, например, obj.myFunctionname(), оператор this внутри myFunctionname относится к obj. Мне интересно, если я смогу принять приключение этого факта. Значение, при наличии fn в качестве параметра syncCall, принимать как-то контекст (который obj) и передать его правильно apply() функцию в качестве первого параметра (таким образом, уйти от того, OBJ в качестве второго входного параметра в syncCall())

+1

* это * не «контекст», это просто параметр, который устанавливается в вызове или с помощью * связать *. Если вы хотите вызывать * syncCall * как 'obj.syncCall', так что * this * внутри функции - * obj *, то добавьте его в * Object.prototype *, чтобы вы делали' obj.syncCall (cb, fn) 'и' ... fn.apply (this, param) ... '. Имейте в виду, что делать это не нравится, потому что он может сломаться плохо написанным для ... петель. Таким образом, у вас может быть конструктор * Obj * и есть 'Obj.prototype.syncCall'. – RobG

+0

@RobG Я пробовал это, когда ты совершенно прав. Объекты, которые я пытался расширить путем прототипирования, имели некоторые особенности для построения и начали вести себя непредсказуемо, имея новый свойство/функцию asyncCall. Таким образом, я выбрал решение, предложенное «этими бабами» ниже – BartoszK

ответ

1

Если вы хотите избавиться от obj param fn, должны быть контекстуальными (это) агностическими, потому что вы должны пройти как fn любой вызываемый (например, анонимную функцию, которая не использует это), так что 1) передать функцию, связанную с obj или 2) оставить контекст как is и call .apply без контекста param fn.apply(null, params):

1) если вызываемый привязанный привязанный fn к объекту:

syncCall(cb, fn.bind(obj)) 

или

2) при вызове в OBJ контексте оставить сноска как

obj = { 

fn: function(){ 
    // some logic to be done in syncCall 
}, 

someObjMethod: function(){ 
    syncCall(cb, this.fn); //here this == obj and will be inside syncCall 
} 
} 
+1

p.s .: По соглашению cb является последним параметром, поэтому замените его на подпись 'syncCall' на' syncCall (fn, cb) ':) – thesebas

Смежные вопросы