SORU
8 Ocak 2010, Cuma


Başvuru koruyarak "bu" JavaScript prototip fonksiyonları

Sadece ilk JavaScript kullanarak yapıyorum ve sorun kapsamı değiştiğinde bir prototip işlevi içinden ana nesne this bir başvuru korumak için nasıl sergiyi yaşıyorum. Benim demek istediğim (burada jQuery kullanıyorum) açıklamak gerekirse:

MyClass = function() {
  this.element = $('#element');
  this.myValue = 'something';

  // some more code
}

MyClass.prototype.myfunc = function() {
  // at this point, "this" refers to the instance of MyClass

  this.element.click(function() {
    // at this point, "this" refers to the DOM element
    // but what if I want to access the original "this.myValue"?
  });
}

new MyClass();

myfunc başında bunu yaparak ana nesnesine bir başvuru koru biliyorum:

var myThis = this;

ve sonra myThis.myValue ana nesne özelliğine erişmek için kullanıyor. Ama MyClass prototip fonksiyonları bir sürü var ne olur? Her birinin başında this referansı kaydetmek zorunda mıyım? Daha temiz bir yolu olmalı gibi görünüyor. Ve böyle bir durumu ne olacak:

MyClass = function() {
  this.elements $('.elements');
  this.myValue = 'something';

  this.elements.each(this.doSomething);
}

MyClass.prototype.doSomething = function() {
  // operate on the element
}

new MyClass();

Bu durumda, yapamam oluşturmak için bir referans ana nesne ile var myThis = this; çünkü özgün değeri this kapsamında doSomething jQuery nesne değil, bir MyClass nesne.

Bana orijinal referansı tutmak için global bir değişken kullanmak için önerilen oldu this, ama öyle görünüyor ki benim için gerçekten kötü bir fikir gibi. Genel ad kirletmek istemiyorum ve bunları birbirleriyle engel olmadan MyClass iki farklı nesne başlatmasını engellemek olacak gibi görünüyor.

Herhangi bir öneriniz var mı? Temiz bir şekilde sonra ben ne için vardır? Ya da tüm tasarım desen kusurludur?

CEVAP
8 Ocak 2010, Cuma


İçin koruma kapsamında, bind yöntem çok faydalı oldu, şimdi bir parçası son zamanlarda yayımlanan ECMAScript 5th Edition Şartname, uygulama bu işlevi basit (sadece 8 satır):

// The .bind method from Prototype.js 
if (!Function.prototype.bind) { // check if native implementation available
  Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
      return fn.apply(object, 
        args.concat(Array.prototype.slice.call(arguments))); 
    }; 
  };
}

Ve bu şekilde örnek olarak kullanabilirsiniz:

MyClass.prototype.myfunc = function() {

  this.element.click((function() {
    // ...
  }).bind(this));
};

Başka bir örnek:

var obj = {
  test: 'obj test',
  fx: function() {
    alert(this.test   '\n'   Array.prototype.slice.call(arguments).join());
  }
};

var test = "Global test";
var fx1 = obj.fx;
var fx2 = obj.fx.bind(obj, 1, 2, 3);

fx1(1,2);
fx2(4, 5);

Bu ikinci örnekte daha fazla bind davranışlarını gözlemliyoruz.

bind ilk argüman olarak tanımlanan fonksiyon, işlev, bağlam (this değer) koruma, arama sorumlu olacak temelde yeni bir işlev oluşturur.

Bağımsız kalan sadece bizim işleve geçirilir.

İşlevi fx1, herhangi olmadan başlatılan bu örnek dikkat edinbağlam nesnesi(obj.method() ), basit bir işlev çağrısı, invokation bu tip this anahtar içinde Genel nesneyi ifade eder gibi, uyaracaktır "". küresel test

Şimdi, fx2 yeni işlev bind yöntem oluşturulmuş olacak çağrı işlevi koruma bağlamında ve doğru geçirmeden bağımsız olacak uyarı "n test 1, 2, 3, 4, 5" çünkü biz onu çağıran ekleme ayrıca iki bağımsız değişken, o zaten vardılidirilk üç.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • HowcastFoodDrink

    HowcastFoodD

    21 EYLÜL 2010
  • karneson

    karneson

    23 Temmuz 2006
  • MndsgnVEVO

    MndsgnVEVO

    26 Kasım 2013