2011-06-13 32 views
8

Böyle bir işlevi varsa:Arayan işlevinin 'bu' değerini nasıl alırsınız?

function foo(_this) { 
    console.log(_this); 
} 

function bar() {} 
bar.prototype.func = function() { 
    foo(this); 
} 

var test = new bar(); 
test.func(); 

sonra bar ait test örneği açmış olur.

Ancak, bunun çalışması için bar.prototype.func işlevinde this iletmem gerekiyor. this'u geçmeden olmadandeğeri değerini almanın mümkün olup olmadığını merak ediyordum.

arguments.callee.caller kullanmayı denedim, ancak bu, prototip işlevinin içinde this değerinin değil prototip işlevinin kendisini döndürür.

bartest örneğinin prototip işlevinde yalnızca foo() numaralı telefonu arayarak loglanması mümkün mü?

+1

yok çağrı yığını kadar fonksiyonlarının bağlamını erişemez. Bu bağlamı geçmelisin. – Raynos

+0

Çubuğun prototipine eklenmek için özel bir amaç işlevi oluşturmaya devam ediyorsanız, bunu 'bunu yapmak istememenizin bir nedeni var mı? Bu modeli kullanmak için öğrenme amaçlarından başka bir sebep var mı? – TNi

+0

@TNi: Her zaman pratik bir amacı yoktur, ancak senaryoda yararlı olacaktır. Sadece bir işlev geçirerek ve döngüler için olduğu gibi işlevi yürüten bir işleve bağlı olarak döngü için çok düzeyli bir yapı oluşturmaya çalışıyorum.Döngüsel bir döngüde, buna 'bu' erişebilir, ancak bu şekilde bu işlevi işlevime iletmem gerektiği gibi görünüyor. – pimvdb

cevap

3

Eğer cevap ardından '(herhangi bir yöntemle) Bu geçmeden' hayır

değer olabilir olduğunu Ancak alternatif yöntemlerle geçti. Örneğin, global var (Bar sınıfında) veya oturum veya çerezleri kullanarak.

function bar() { 

     var myThis; 

     function foo() { 
      console.log(myThis); 
     } 

     bar.prototype.func = function() { 

      myThis = this; 
      foo(); 
     } 
    } 

    var test = new bar(); 
    test.func(); 
+2

tarafından oluşturulan örnek olmak, hala bu 'etrafında' geçiyor. Ben foo.apply (bu) 'yi çok daha temiz/daha az hacksi buluyorum. – Raynos

+1

Ben bunu geçmiyorum, ancak Bar sınıfının ad alanı içinde erişilebilen bir değişkene değer ayarlamıyorum. Bu, bunu yapmak için iyi ve doğru bir yoldur. –

+1

@Raynos: Bu doğru, ancak bunun mümkün olmadığını belirttiğim için kabul ettim. Bu temelde sorumu cevaplıyor. – pimvdb

1

Ben çalışması gerekir bar kapsamında foo arayarak düşünüyorum: sorudur

function foo() { 
    console.log(this.testVal); 
} 

function bar() { this.testVal = 'From bar with love'; } 
bar.prototype.func = function() { 
    foo.call(this); 
} 

var test = new bar(); 
test.func(); //=> 'From bar with love' 
+0

Teşekkürler ama hala 'bu' değerini geçmem gerekiyor. Demek istediğim, 'foo' içinde' 'foo'' sözcüğünü' func' içinde 'foo() ile çağırabilmem gerekir. – pimvdb

+0

Ama ehr, burada olan bu mu, yoksa sorunuzu yanlış anlamış mıyım? Benim cevabımdaki gibi foo çağırmak, 'bu' örneğini 'test' 'in foo' ya getirdiğini, testVal özelliğini 'log' aracılığıyla günlüğe kaydederek gösterildiği gibi yapar. – KooiInc

+0

Net olmamak için üzgünüm. Ben "foo" içindeki "bu" func'yi "func" içinde "bu" kelimesini geçmeden elde etmeyi kastettim. – pimvdb

0

Bunu, harici işlevi değiştirmeden yapabilirsiniz, ancak sizin arama şeklinizi değiştirmeniz gerekir.

Arayanın bağlamını alamıyorsunuz, ancak apply veya call yöntemiyle çağıran bir işleve this özelliğini ayarlayabilirsiniz. this'da bir açıklama için this reference'a bakın. this kullanıldığında

function foo() 
{ 
    console.log(this); 
} 

function bar() 
{ 
    bar.prototype.func = function func() 
    { 
     foo.apply(this); 
    }; 
} 

var test = new bar(); 
test.func(); 

Genellikle, bir nesne yönelimli bağlamda var. Bir nesnenin bir yöntemini başka biriyle çağırmaya çalışmak, zayıf tasarımı gösterebilir. Daha uygulanabilir tasarım kalıpları için elde etmeye çalıştığınız şeyleri biraz daha açıklayın.

Javascript OOP paradigmasının bir örneği için, my answer here'u kontrol edin.

1

Buna ne dersiniz?

"use strict"; 
var o = { 
    foo : function() { 
     console.log(this); 
    } 
} 

function bar() {} 
bar.prototype = o; 
bar.prototype.constructor = bar; 
bar.prototype.func = function() { 
    this.foo(); 
} 

var test = new bar(); 
test.func(); 

Ya da bu:

"use strict"; 
Function.prototype.extender = function(o){ 
    if(typeof o == 'object'){ 
     this.prototype = o; 
    }else if (typeof o == 'function') { 
     this.prototype = Object.create(o.prototype); 
    }else{ 
     throw Error('Error while extending '+this.name); 
    } 
    this.prototype.constructor = this; 
} 
var o = { 
    foo : function() { 
     console.log(this); 
    } 
} 

function bar() {} 
bar.extender(o); 
bar.prototype.func = function() { 
    this.foo(); 
} 

var test = new bar(); 
test.func(); 
İlgili konular