20

现在,虽然我知道您不能像在 C# 中那样执行继承,但我在 Internet 上看到它提到它是可能的。如果无法使用纯 JavaScript 代码,那么是否可以使用Ext JS,如果可以,怎么办?

4

6 回答 6

49

JavaScript 面向对象范式是基于原型的。没有“类”,只有对象。

您可以通过不同的方式实现继承。两个更流行的替代方案是“伪经典”和“原型”形式。例如:

伪经典继承

我认为这是最流行的方式。您创建与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();

原型继承

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

// 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;
}
于 2009-10-19T04:23:06.657 回答
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 中的每个对象都可以访问Object.prototype. 如果您要为所有对象创建自定义方法,您会这样做:

Object.prototype.foo = function(){};
alert( typeof ({}).foo ) // 'function'

关键说明:

  • 该词this用于引用当前对象,因此在调用this.name时设置正在创建的对象的名称属性。new person
  • constructorName.prototype.nameOfMethod = function(){} 在定义构造函数之后,您可以在构造函数上定义新的原型方法。您不需要在构造函数内部定义它,这样效率更高。
  • 除非您在对象上显式定义属性,否则对于john我创建的对象,由于没有getName直接附加到john对象的方法,解释器需要到达john对象的原型,即person.prototype从那里访问方法。您可以使用hasOwnProperty来查看对象是否直接拥有属性。

参考:

于 2009-10-19T04:21:39.530 回答
3

如果你做过 JavaScript 中的面向对象编程,你就会知道可以创建一个类,如下所示:

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

到目前为止,我们的类 person 只有两个属性,我们将给它一些方法。一个干净的方法是使用它的“原型”对象。从 JavaScript 1.1 开始,原型对象在 JavaScript 中被引入。这是一个内置对象,可简化向对象的所有实例添加自定义属性和方法的过程。让我们使用它的“原型”对象向我们的类添加 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() {}。我们使用这个内部类的原因是为了避免混淆 baseClass 和 subClass 原型。接下来我们让继承类的原型指向 baseClass 原型,代码如下:inheritance.prototype = baseClass。原型; 然后我们将继承原型复制到子类原型中,如下: subClass.prototype = new inherit(); 接下来是为我们的子类指定构造函数,如下所示: 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 方法,并在我们的例子中传递了 subClass Manager,然后传递了 baseClass Person。请注意,这里的顺序非常重要。如果您交换它们,继承将不会按您的预期工作。另请注意,您需要先指定此继承,然后才能实际定义我们的子类。现在让我们定义我们的子类:

我们可以添加更多方法,如下所示。我们的 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

于 2011-12-21T20:22:57.417 回答
0

JavaScript 是基于原型的继承。但是,如果您使用 Ext-js,它将允许您使用更经典的继承语法。请注意,它仍在进行原型设计,因此您应该注意一些细微差别。主要是加载和运行,因此加载脚本的顺序很重要,并且类定义基本上位于内存中。

那里有一些很好的教程。我建议阅读最初的文档并观看此视频。Ext 在使 JavaScript 更像 Java 或 C# 方面做得非常好,并减少了您编写的标记量。然而,权衡是您对自定义组件有更高的学习曲线。一旦你更好地掌握了语言的范围,你将能够更好地使用 mixins 和函数来减少对继承的需求。

于 2014-01-22T18:04:33.787 回答
0

你可以试试

subClass.prototype.__proto__ = baseClass.prototype;

详情请访问我的网站

于 2014-11-02T09:13:49.330 回答
0

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

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();
于 2017-12-06T12:18:00.053 回答