Как изменить объявления класса Prototype в jquery? - PullRequest
3 голосов
/ 10 октября 2011

Я работаю с моей миграцией на Rails 3.1, и становится все труднее поддерживать мирное соседство jquery и прототипа. Я изучаю способ преобразования js-файлов, реализованных в Prototype, в формат jquery.

Я использовал метод прототипа объявления классов и подклассов:

// properties are directly passed to `create` method
var Person = Class.create({
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
});

// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
  // redefine the speak method
  say: function($super, message) {
    return $super(message) + ', yarr!';
  }
});

var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"

Я читал о сценарии Джона Резига: http://ejohn.org/blog/simple-javascript-inheritance/. Это путь? Или я должен выбрать другой подход?

У меня около 15 js-файлов (один класс на файл). Я готов потратить некоторое время на эту миграцию, поэтому я бы хотел сделать это правильно. Спасибо за вашу профессиональную помощь!

Ответы [ 4 ]

2 голосов
/ 10 октября 2011

Вот один из возможных способов реализации вашего примера с простыми функциями.

function Person(name) {
  this.name = name;
}

Person.prototype.say = function (message) {
  return this.name + ": " + message;
};

function Pirate(name) {
  this._super = Person.prototype;
  this._super.constructor.apply(this, arguments);
}

Pirate.prototype.say = function (message) {
  return this._super.say.apply(this, arguments) + ", yarr!";
};

john = new Pirate("Long John");
john.say("ahoy matey");

Возможно, вы захотите извлечь операции наследования в функцию, но это дает вам основную идею.

1 голос
/ 10 октября 2011

Это немного улучшенная версия примера Джимми.Во-первых, я бы добавил дополнительную функцию, которая поможет вам более удобно определять цепочку прототипов.Вы также можете использовать Object.create(), но это еще не поддерживается во всех браузерах, поэтому эта функция должна быть более пуленепробиваемой:

// A convenient function to define prototype chain

function inheritPrototype(child, parent) {
  function F(){}
  F.prototype = parent.prototype;
  child.prototype = new F();
  // set the constructor back to the original, explained later
  child.prototype.constructor = child;
}

Затем определите объекты.Обратите внимание на дополнительную функцию setName, которая позволяет нам установить имя человека.(не говоря уже о том, что в JS обычно нет необходимости в методах получения / установки).Также обратите внимание на дополнительный вызов inheritPrototype после определения функции Pirate.

function Person(name) {
  this.name = name;
}

Person.prototype.say = function (message) {
  return this.name + ": " + message;
};

Person.prototype.setName = function(name) {
  this.name = name;
};

function Pirate(name) {
  this._super = Person.prototype;
  this._super.constructor.apply(this, arguments);
}

inheritPrototype(Pirate, Person);

Pirate.prototype.say = function (message) {
  return this._super.say.apply(this, arguments) + ", yarr!";
};

var john = new Pirate("Long John");
john.say("ahoy matey");

Этот стиль позволяет автоматически вызывать функции родителя, и вам не нужно переопределять каждую из них, еслиони такие же, как их родители.Также это не мешает вам переопределить функции, которые уже существуют для родителя (в этом случае say переопределяется).И помните, что все функции односторонние, что означает, что если вы переопределите функцию в дочерних элементах, то функция родителя останется неизменной.Пример:

// Should result in John "The Pirate" Long: ahoy matey, yarr! 
// instead of how it was defined in Person 
john.setName('John "The Pirate" Long');
john.say('ahoy matey');

// Notice that even though Pirate redefined say function, it
// still works as defined in Person, if it's called on a Person object
var president = new Person("Obama");
president.say('Vote for me!');

Также использование этого стиля позволяет проверять типы объектов, если child.prototype.construtor был переопределен для child (замена прототипа устанавливает его в функцию конструктора parent).Джон - это Человек и Пират (потому что Пират наследует от Человека).Пример:

john instanceof Person
> true
john instanceof Pirate
> true

Поскольку президент является непосредственно объектом Person, а не пиратом, результаты будут следующими:

president instanceof Person
> true
president instanceof Pirate
> false
0 голосов
/ 30 августа 2012

Взгляните на базу Дина Эдварда: js: http://dean.edwards.name/weblog/2006/03/base/

var object = new Base;
object.method = function() {
  alert("Hello World!");
};
object.extend({
  method: function() {
    // call the "super" method
    this.base();
    // add some code
    alert("Hello again!");
  }
});
object.method();
// ==> Hello World!
// ==> Hello again!

Если вы вызываете _super напрямую, вы можете столкнуться с проблемами, если метод super также использует this._super, а затем запускается как бесконечный цикл, поскольку вы всегда передаете один и тот же объект как this

0 голосов
/ 10 октября 2011

jQuery не имеет понятия о классах.Это библиотека, которая построена, чтобы абстрагироваться от различий браузера и упростить процесс общих операций; манипулирование DOM , AJAX и обработка событий .

...