首先,在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继承的方法 - Python技术站