在JavaScript中执行继承

时间:2009-10-19 04:13:40

标签: javascript inheritance extjs prototypal-inheritance

现在虽然我知道你不能像在C#中那样执行继承,但我已经看到它在互联网上提到它有可能。如果使用普通的JavaScript代码是不可能的,那么可以使用Ext JS吗?如果可以,那么如何使用?

6 个答案:

答案 0 :(得分:47)

JavaScript面向对象的范例是prototype based。没有“类”,只有对象。

您可以通过不同方式实现继承。两种更受欢迎的替代品是“伪经典”和“原型”形式。例如:

伪古典继承

我认为这是最受欢迎的方式。您创建与constructor functions运算符一起使用的new,并通过构造函数原型添加成员。

// Define the Person constructor function
function Person() {}

Person.prototype.sayHello = function(){
    alert ('hello');
};

// Define the Student constructor function
function Student() {}

// Inherit from Person
Student.prototype = new Person();

// Correct the constructor pointer, because it points to Person
Student.prototype.constructor = Student;

// Replace the sayHello method (a polymorphism example)
Student.prototype.sayHello = function () {
    alert('hi, I am a student');
}

var student1 = new Student();
student1.sayHello();

Prototypal inheritance

基本上我们创建一个辅助函数,它将一个对象作为参数并返回一个从旧的继承的空新对象,对象继承自对象

// Helper function
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

var person = {
    sayHello : function () {
        alert('Person object');
    },
    walk : function () {
        alert('walk');
    }
};

var student1 = Object.create(person);
student1.sayHello = function () {
    alert('hello I am a student');
};

另一个有趣的形式是寄生继承。在“派生”构造函数中,您将创建一个“基础”对象实例。该对象被扩充并返回新实例:

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

function Student(value) {
    var that = new Person(value);
    that.sayHello = function () {
        alert('hello I am a student');
    };
    return that;
}

答案 1 :(得分:3)

JavaScript继承是通过原型完成的。您没有使用class关键字定义任何内容,但是您创建了一个用作构造函数的函数来构建新对象(使用new关键字)。

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

person.prototype.getName = function() {
    return this.name;
}

var john = new person('john');
alert( john.getName() );

您可以使用以下方法访问此原型方法:

person.prototype.getName

所有新创建的对象都是基于核心构造函数(有时被来自经典继承语言的人称为类或核心对象)构建的,例如Object,因此JavaScript中的每个对象都可以访问{{1 }}。如果您要为所有对象创建自定义方法:

Object.prototype

主要提示:

  • Object.prototype.foo = function(){}; alert( typeof ({}).foo ) // 'function' 字用于引用当前对象,因此this设置调用this.name时正在创建的对象的name属性。
  • 您可以在定义构造函数后使用new person 在构造函数上定义新的原型方法。您不需要在构造函数内部定义它,并且这种方式更有效。
  • 除非您明确定义对象的属性,否则使用我创建的constructorName.prototype.nameOfMethod = function(){}对象,因为没有john方法直接附加到getName对象,解释器需要旅行直到john对象的原型,即john并从那里访问该方法。您可以使用person.prototype查看对象是否直接拥有某个属性。

参考:

答案 2 :(得分:3)

如果您已在JavaScript中完成面向对象编程,您将知道可以按如下方式创建类:

Person = function(id, name, age){
    this.id = id;
    this.name = name;
    this.age = age;
    alert('A new person has been accepted');
}

到目前为止,我们的班级人员只有两个属性,我们将给它一些方法。一个干净的方法是这样做 使用它的'原型'对象。 从JavaScript 1.1开始,原型对象是在JavaScript中引入的。这是一个内置的对象 简化了向对象的所有实例添加自定义属性和方法的过程。 让我们使用'prototype'对象为我们的类添加2个方法,如下所示:

Person.prototype = {
    /** wake person up */
    wake_up: function() {
        alert('I am awake');
    },

    /** retrieve person's age */
    get_age: function() {
        return this.age;
    }
}

现在我们已经定义了我们的类Person。如果我们想要定义另一个名为Manager的类,它从Person继承了一些属性,该怎么办?在定义Manager类时,没有必要再次重新定义所有这些属性,我们可以将其设置为继承Person类。 JavaScript没有内置继承,但我们可以使用一种技术来实现继承,如下所示:

Inheritance_Manager = {}; //我们创建一个继承管理器类(名称是任意的)

现在让我们给继承类一个名为extend的方法,它接受baseClass和subClassas参数。 在extend方法中,我们将创建一个名为inheritance function inheritance(){}的内部类。我们之所以使用这种内心 class是为了避免baseClass和subClass原型之间的混淆。 接下来,我们将继承类的原型指向baseClass原型,如下面的代码: inheritance.prototype = baseClass。原型; 然后我们将继承原型复制到subClass原型中,如下所示:subClass.prototype = new inheritance(); 接下来要为我们的subClass指定构造函数,如下所示:subClass.prototype.constructor = subClass; 完成我们的子类原型设计后,我们可以指定接下来的两行代码来设置一些基类指针。

subClass.baseConstructor = baseClass;
subClass.superClass = baseClass.prototype;

以下是我们的扩展功能的完整代码:

Inheritance_Manager.extend = function(subClass, baseClass) {
    function inheritance() { }
    inheritance.prototype = baseClass.prototype;
    subClass.prototype = new inheritance();
    subClass.prototype.constructor = subClass;
    subClass.baseConstructor = baseClass;
    subClass.superClass = baseClass.prototype;
}

现在我们已经实现了继承,我们可以开始使用它来扩展我们的类。在这种情况下,我们将 将我们的Person类扩展为Manager类,如下所示:

我们定义Manager类

Manager = function(id, name, age, salary) {
    Person.baseConstructor.call(this, id, name, age);
    this.salary = salary;
    alert('A manager has been registered.');
}

我们将其继承为Person

Inheritance_Manager.extend(Manager, Person);

如果您注意到,我们刚刚调用了Inheritance_Manager类的extend方法,并在我们的case中传递了subClass Manager,然后传递了baseClass Person。请注意,订单在这里非常重要。如果你交换它们,继承 如果有的话,将无法按预期工作。 另请注意,在实际定义subClass之前,需要指定此继承。 现在让我们定义我们的子类:

我们可以添加更多方法,如下所示。我们的Manager类将始终具有Person类中定义的方法和属性,因为它继承了它。

Manager.prototype.lead = function(){
   alert('I am a good leader');
}

现在要测试它,让我们创建两个对象,一个来自Person类,另一个来自继承的类Manager:

var p = new Person(1, 'Joe Tester', 26);
var pm = new Manager(1, 'Joe Tester', 26, '20.000');

随时获取完整代码和更多评论: http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx

答案 3 :(得分:0)

JavaScript是prototype based继承。但是,如果使用Ext-js,它将允许您使用更多经典继承语法的语法。请注意它仍然是引擎盖下的原型,所以你应该注意一些细微差别。主要是它是加载和去,所以你加载脚本的顺序很重要,你的类定义基本上在内存中。

那里有一些好tutorials。我建议通过初始文档并观看video。 Ext在使JavaScript更像Java或C#以及减少你编写的标记量方面做得非常好。然而,权衡的是您有更高的学习曲线来定制组件。一旦你更深入地掌握了语言的范围,你就可以更好地使用mixins,函数来减少继承的需要。

答案 4 :(得分:0)

您可以尝试

subClass.prototype.__proto__ = baseClass.prototype;

详情请访问my website

答案 5 :(得分:0)

这是一个简单的继承示例。 ClassA是父类,ClassB是子类,常见任务是通过ClassB调用ClassA的print方法,因此这里第一个初始化构造函数然后为父类创建原型方法。

var ClassA = function() {
this.name = "class A";
 }
var a = new ClassA();
ClassA.prototype.print = function() {
alert(this.name);
}

var inheritsFrom = function (child, parent) {
 child.prototype = Object.create(parent.prototype);
 };
var ClassB = function() {
     this.name = "class B";
     this.surname = "I'm the child";
 }

 inheritsFrom(ClassB, ClassA);
 var b = new ClassB();
 b.print();