沃梦达 / IT编程 / 前端开发 / 正文

javascript基于prototype实现类似OOP继承的方法

首先,在JavaScript中,没有像其他面向对象编程语言(如Java和C#等)那样的类(class)机制。但是,JavaScript使用了原型(prototype)机制,来模拟面向对象的继承和多态性。

首先,在JavaScript中,没有像其他面向对象编程语言(如Java和C#等)那样的类(class)机制。但是,JavaScript使用了原型(prototype)机制,来模拟面向对象的继承和多态性。

下面是基于原型实现JavaScript中的继承机制的完整攻略:

1.对象与原型

在JavaScript中,每个对象都有一个关联的原型对象,这个关联就是通过该对象内部的 [[Prototype]] 属性来实现的。如果在对象中找不到指定的属性或方法,引擎会使用该对象的原型对象进行查找,如果还找不到,会继续往上面的原型链中查找,直到找到为止。

例如,有如下代码示例:

var parent = { name: 'parent' };
var child = { age: 10 };
console.log(child.name); // undefined
child.__proto__ = parent;
console.log(child.name); // 'parent'

上述代码定义了两个对象 parent 和 child,其中 child 可以通过 __proto__ 将其原型对象设置为 parent 对象,这样 child 对象就可以访问 parent 对象中的属性和方法了。因此,上述代码的输出结果是 undefined'parent'

注意:__proto__ 是一个非标准的属性,在一些浏览器中可以使用,但是不建议使用该属性来设置对象的原型,而应该使用 Object.create() API 方法。

2.利用原型链实现继承

利用 JavaScript 中的原型链,可以实现面向对象编程中的继承。在原型继承模型中,每个对象都有一个原型,并且原型可以有自己的原型,形成原型链,从而实现对象之间的继承关系。

例如,有如下的代码示例:

// 定义一个动物对象
var Animal = function (name) {
   this.name = name;
   this.showName = function () {
     console.log(this.name);
   };
}
// 定义一个狗对象并继承自动物
var Dog = function (name) {
   this.name = name;
}
Dog.prototype = new Animal(); // 原型链继承,Dog继承Animal
var dog = new Dog('小黄');
dog.showName(); // '小黄'

上述代码定义了两个对象 Animal 和 Dog,其中 Dog 对象通过 Dog.prototype = new Animal() 继承自 Animal 对象。这样,Dog 对象就可以继承 Animal 对象中的属性和方法了。

3.利用构造函数实现继承

构造函数继承可以通过 call()apply() 方法来实现。这种方式的本质是在新对象上执行构造函数,并传递相应的参数。

例如,有如下的代码示例:

// 定义一个人类对象
var Person = function (name, age) {
   this.name = name;
   this.age = age;
   this.showInfo = function () {
     console.log('name:' + this.name + ',age:' + this.age);
   };
}
// 定义一个学生对象并继承自人类
var Student = function (name, age, score) {
   Person.call(this, name, age); // 调用Person构造函数的代码
   this.score = score;
   this.showScore = function () {
     console.log('score:' + this.score);
   };
}
var student = new Student('张三', 18, 90);
student.showInfo(); // 'name:张三,age:18'
student.showScore(); // 'score:90'

上述代码定义了两个对象 Person 和 Student,其中 Student 对象通过 Person.call(this, name, age) 在构造函数中调用父类 Person 的构造函数,从而实现了继承。

4.示例代码

最后,我们来看两段示例代码。

4.1 构造函数继承示例

// 父类Person
function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() {
  return this.name;
}

// 子类Student
function Student(name, id) {
  Person.call(this, name); // 继承属性
  this.id = id;
}
Student.prototype = new Person();// 继承方法
Student.prototype.getId = function() {
  return this.id;
};

var student1 = new Student('Tom', 123456);
console.log(student1.getName()); // Tom
console.log(student1.getId()); // 123456

上述示例代码中,父类 Person 声明了 getName() 方法,子类 Student 重写了父类的 getName() 方法,同时通过使用 call() 方法调用了父类的构造函数,从而实现了继承。

4.2 原型链继承示例

// 父类Person
function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() {
  return this.name;
};

// 子类Student
function Student(name, id) {
  this.id = id;
}
Student.prototype = new Person();
Student.prototype.getId = function() {
  return this.id;
};

var student2 = new Student('Jerry', 654321);
console.log(student2.getName()); // Jerry
console.log(student2.getId()); // 654321

上述示例代码中,子类 Student 直接继承了父类 Person,并且重写了方法 getId()。此时,子类也就拥有了父类的所有方法和属性,通过实例化子类对象后,就可以调用本身和父类的方法和属性了。

本文标题为:javascript基于prototype实现类似OOP继承的方法