2009-01-19 24 views
124

"Bu" değişkeni ayarlamak için iyi bir yol bulamadığım dışında Javascript konusunda oldukça iyi bir fikrim var. Şunları düşünün:"Bu" değişkeni kolayca ayarlayın.

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body; //using body as example object 
someObj.foo_variable = "hi"; //set foo_variable so it alerts 

var old_fn = someObj.fn; //store old value 
someObj.fn = myFunction; //bind to someObj so "this" keyword works 
someObj.fn();    
someObj.fn = old_fn;  //restore old value 

Son 4 satır olmadan bunu yapmanın bir yolu var mı? Oldukça sinir bozucu ... Ben güzel ve zeki olduğunu düşündüm anonim işlev, bağlayıcı çalıştı, ama boşuna ettik: Açıkçası

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body;  //using body as example object 
someObj.foo_variable = "hi";  //set foo_variable so it alerts 
someObj.(function(){ fn(); })(); //fail. 

, myFunction içine değişken geçirmeden bir seçenektir ... ama bu bu sorunun amacı değil.

Teşekkürler.

cevap

207

JavaScript, call() ve apply() tüm fonksiyonlar için tanımlanan iki yöntem vardır. Ne bu işlevler yapmak bu-nesne parametrenin değerini atayarak, onlar üzerinde çağrılan edildi işlevini çağırmak olduğunu

call(/* object */, /* arguments... */); 
apply(/* object */, /* arguments[] */); 

: gibi işlev sözdizimi görünüyor. size daha sonra sorunsuz bir şekilde arayabilirsin bir işleve 'mağaza' this değeri için böylece isterseniz (artık bu değere erişimi olmayan zaman mesela)

var myFunction = function(){ 
    alert(this.foo_variable); 
} 
myFunction.call(document.body); 
+3

Ayrıca, jQuery kullanıyorsanız, '$ .proxy (işlev, öğe)' özelliğini kullanabilirsiniz. ne zaman bu functio n denir, eleman bağlamında olacaktır. http://api.jquery.com/jquery.proxy/ –

54

Sana call aradığınız düşünüyorum:

myFunction.call(obj, arg1, arg2, ...); 

Bu obj için this set ile myFunction çağırır.

bir dizi olarak da işlev parametreleri alır biraz farklı bir yöntem apply vardır:

myFunction.apply(obj, [arg1, arg2, ...]); 
+1

Bkz ECMAScript Dil Şartnamede bölüm 15.3.4.3, 15.3.4.4 ve 10.1.8: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

, kullanılabilir değil (bunu bind edebilirsiniz gerçi tüm tarayıcılar) 'de:

var bound = func.bind(someThisValue); 

// ... later on, where someThisValue is not available anymore 

bound(); // will call with someThisValue as 'this' 
+5

FYI 'bind' IE9 +, FF4 +, Safari 5.1.4+ ve Chrome 7+ [(kaynak)] (http: //kangax.github. io/ES5-compat masa/# Function.prototype.bind). Ayrıca doğrudan anonim bir işleve bağlanabilirsiniz: "var myFunction = function() {/ * this = something * /} .bind (something);' – Adam

0

this bağlamak için nasıl Yaptığım arama bulgularımı ilanıyla böylece beni buraya getirdi: 'ECMAScript'e 2015' biz de bu lexically kullanarak ok fonksiyonlarını ayarlayabilirsiniz.

Bkz: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

yerine:

function Person() { 
    setInterval(function growUp() { 
    // The callback refers to the `self` variable of which 
    // the value is the expected object. 
    this.age++; 
    }.bind(this), 1000); 
} 

Biz şimdi yapabilirsiniz:

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person();