2009-07-02 24 views
22
var A=function(){ 
}; 

$.extend(A.prototype, { 
    init:function(){ 
     alert('A init'); 
    } 
}); 
var B=function(){ 

}; 

$.extend(B.prototype,A.prototype,{ 
    init:function(){ 
     alert('B init'); 
    } 
}); 
var p=new A(); 
p.init(); 
var x=new B(); 
x.init(); 

jest powyższym najlepszym sposobem tworzenia klasy i dziedziczenia w jQuery? W pytaniu B, w jaki sposób mogę wywołać init rodzica (podobnie jak super.init() w językach OO)?Dziedziczenie klasy jquery

+0

szuka sposobu, aby to zrobić też żaden z przewidzianych odpowiedzi spełnione mnie. Poniżej przedstawiam alternatywne rozwiązanie jQuery, które wykorzystuje $ .extend i $ .proxy. – xtempore

Odpowiedz

19

Dla OO najlepiej jest szukać poza jQuery. jQuery opiera się na kolekcjach zwróconych przez selektory.

Jeśli chcesz zajęcia, niektóre opcje to: Base2, Joose i JS.Class.

+13

Jak to jest zaakceptowaną odpowiedzią? P: "Czy jest to najlepszy sposób na wykonanie X w jQuery?" Odp .: "Nie używaj jQuery." Dla niektórych z nas to naprawdę nie jest opcja. – umassthrower

+10

@umassthrower Odbierający nie sugeruje, że nie powinien używać jQuery, sugeruje, że jQuery nie zapewnia rozwiązania dla klas. Każda z wymienionych opcji może współistnieć z jQuery. – undefined

5

Jak wywołać metody rodziców:

var B=function(){ 
    A.call(this); 
}; 

$.extend(B.prototype,A.prototype,{ 
     init:function(){ 
       A.prototype.init.call(this); 
       alert('B init'); 
     } 
}); 
5

Jeśli nie chcesz polegać na innych bibliotek, można to zrobić:

function A() {} 
A.prototype.foo = function() {}; 

function B() { 
    A.call(this); 
    //Or, if there are arguments that need to be passed to A(), 
    //this might be preferable: 
    //A.apply(this, arguments); 
} 

B.prototype = new A(); 

//Or, if the browser supports ECMAScript 5 and/or you have a shim for Object.create, 
//it would be better to do this: 
B.prototype = Object.create(A.prototype); 

$.extend(B.prototype, { 
    //set the constructor property back to B, otherwise it would be set to A 
    constructor: B, 
    bar: function() {} 
}); 

Upewnij zdefiniować żadnych właściwości w konstruktorze, zamiast na prototypie, np:

function A() { 
    this.baz = null; 
} 

Zapobiega to niezamierzonemu udostępnianiu właściwości prototypu.

Istnieje kilka bibliotek, które sprawiają prototypal dziedziczenie łatwiejszy:

Notatki:

  • Wszelkie czas prototyp otrzymuje, w tym poprzez rozszerzenie, to najlepszym rozwiązaniem jest ustawić jego właściwość konstruktora z powrotem do właściwego konstruktora. Dlatego stawiamy B.prototype.constructor do B. Gdybyś zastępując A.prototype należy zrobić to tak:

...

A.prototype = { 
    constructor: A, 
    foo: function() {} 
    //other methods... 
} 
  • B.prototype = Object.create(A.prototype) jest preferowany nad B.prototype = new A() ponieważ pomaga wykryć je wcześniej, jeśli zapomnisz zadzwonić do A() z konstruktora B(); pozwala również A() na posiadanie wymaganych parametrów. Będziesz potrzebował podkładki w starszych przeglądarkach; najprostsza podkładka (chociaż nie obsługuje pełnej specyfikacji Object.create) znajduje się na dole tej strony: http://javascript.crockford.com/prototypal.html.
0

Używam tego samego wzoru i podoba mi się jego zwięzłość.

O braku słowa kluczowego "super", to naprawdę nie jest problem. Dzięki funkcji Function.prototype.call() operator może wywoływać dowolną funkcję w kontekście dowolnego obiektu. Zatem sekwencja zadzwonić A.prototype.init() z B.prototype.init() jest:

A.prototype.init.call(this, some parameters ...);

Nie należy również zapominać, że mogą wywołać konstruktor z B konstruktora tak:

B = function(key, name) { 
    A.call(this, key); 
    this.name = name; 
}; 

Eksperymentowany koder JS będzie wiedział, co się stanie.

Podsumowując: nie idealnie, ale wystarczająco blisko.

0

Szukałem czegoś podobnego. Żadna z odpowiedzi udzielonych naprawdę przypadła mi do gustu, więc w końcu miał pęknięcia w niej siebie ...

http://jsfiddle.net/tn9upue0/1/

Przykładowe klasy

  • $ .Animal() tworzy zwierzę rodzajowe , z domyślnymi 4 nogami, że można podać nazwę w jego opcjach i może opisać siebie. $ .Dog() jest podklasą Animal, która idzie "woof" i może znać pewne sztuczki . $ .Cat() jest podklasą Animal, która brzmi "miau". $ .Bird() to podklasa Animal, która ma 2 nogi i przechodzi "tweet".

implementacja klasy

  • Każda podklasa zwierzę tworzy instancję o nazwie $ .Animal rodzica, które mogą być wykorzystane później zadzwonić metody rodzica. Podczas wywoływania metody nadrzędnej może być ważny kontekst. W takim przypadku należy wywołać metodę $ .proxy(), przekazując ją jako kontekst.

Przykâadowa

Nazywam jest nieznany. Jestem zwierzęciem z 4 nogami.

Nazywam się Rover. Jestem zwierzęciem z 4 nogami. Mówię "woof". Mogę usiąść, zostać i przewrócić się.

Nazywam się mitenki. Jestem zwierzęciem z 4 nogami. Mówię "miau".

Moje nazwisko nie jest znane. Jestem zwierzęciem z 2 nogami. Mówię "tweet".

Przykładowy kod

$.Animal = function (options) { 
    return { 
     options: options || {}, 

     _getName: function() { 
      return this.options.name || 'unknown'; 
     }, 

     _getLegs: function() { 
      return 4; 
     }, 

     describe: function() { 
      return 'My name is ' + this._getName() + '. I am an animal with ' + this._getLegs() + ' legs.'; 
     } 
    } 
}; 

$.Dog = function (options) { 
    var parent = $.Animal(options); 
    return $.extend({}, parent, { 
     describe: function() { 
      var s = $.proxy(parent.describe, this)() + ' I say "woof".'; 
      if (this.options.tricks) { 
       s += ' I can ' + this.options.tricks + '.'; 
      } 
      return s; 
     } 
    }); 
}; 

$.Cat = function (options) { 
    var parent = $.Animal(options); 
    return $.extend({}, parent, { 
     describe: function() { 
      return $.proxy(parent.describe, this)() + ' I say "meow".'; 
     } 
    }); 
}; 

$.Bird = function (options) { 
    var parent = $.Animal(options); 
    return $.extend({}, parent, { 
     _getLegs: function() { 
      return 2; 
     }, 

     describe: function() { 
      return $.proxy(parent.describe, this)() + ' I say "tweet".'; 
     } 
    }); 
}; 

var animal = $.Animal(), 
    rover = $.Dog({name: 'Rover', tricks: 'sit, stay, and roll over'}), 
    mittens = $.Cat({name: 'Mittens'}), 
    bird = $.Bird(); 
$('#out').html(
    animal.describe() + '<br>' + 
     rover.describe() + '<br>' + 
     mittens.describe() + '<br>' + 
     bird.describe() 
); 
Powiązane problemy