如何将Prototype类声明更改为jquery?

时间:2011-10-10 08:22:45

标签: javascript jquery ruby-on-rails ruby-on-rails-3.1 prototype-programming

我正在使用我的Rails 3.1迁移,并且越来越难以保持jquery和原型并行生活。我正在研究一种将我的Prototype-way实现的js文件改为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!"

我读过John Resig的剧本:http://ejohn.org/blog/simple-javascript-inheritance/。这是要走的路吗?或者我应该选择其他方法吗?

我有大约15个js文件(每个文件一个类)。我愿意花一些时间进行这次迁移,所以我想做得对。感谢您的专业帮助!

4 个答案:

答案 0 :(得分:2)

这是使用普通函数实现示例的一种可能方法。

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 :(得分:1)

这是Jimmy的一个改进版本的例子。首先,我添加了一个额外的功能,可以帮助您更方便地定义原型链。你也可以使用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,它使我们能够设置Person的名称。 (没关系,在JS中,通常不需要getter / setter)。在定义了Pirate函数后,还要注意额外的inheritPrototype调用。

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(替换原型将其设置为父的构造函数),则使用此样式还可以检查对象类型。约翰既是人又是海盗(因为海盗继承自人)。一个例子:

john instanceof Person
> true
john instanceof Pirate
> true

由于总统直接是Person对象而不是Pirate,因此结果将如下:

president instanceof Person
> true
president instanceof Pirate
> false

答案 2 :(得分:0)

jQuery没有类的概念。它是一个用于抽象浏览器差异并简化常见操作过程的库; DOM manipulationAJAXevent handling

答案 3 :(得分:0)

看看Dean Edward的Base.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”传递。