JavaScript是怎么样实现继承的?
参考答案:
在JavaScript中,实现继承的主要方式是通过原型链(Prototype Chain)。每个JavaScript对象都有一个指向它的原型(prototype)的链接。当试图访问一个对象的属性时,如果它自身没有这个属性,那么JavaScript会在它的原型上寻找这个属性,这就是原型链。
在JavaScript中,构造函数(Constructor)和原型(Prototype)是实现继承的两个关键部分。
下面是一个简单的JavaScript继承示例:
// 定义父类
function Parent(name) {
this.name = name;
this.play = [1, 2, 3];
}
Parent.prototype.getName = function() {
return this.name;
}
Parent.prototype.hello = function() {
console.log('Hello, I am ' + this.name);
}
// 定义子类
function Child(name, age) {
// 调用父类的构造函数
Parent.call(this, name);
this.age = age;
}
// 让子类继承父类的原型
Child.prototype = Object.create(Parent.prototype);
// 修复构造函数指向
Child.prototype.constructor = Child;
// 添加子类特有的方法
Child.prototype.sayAge = function() {
console.log('My age is ' + this.age);
}
// 创建一个子类实例
var child = new Child('Tom', 10);
console.log(child.getName()); // Tom
child.hello(); // Hello, I am Tom
child.sayAge(); // My age is 10
// 修改父类原型上的属性,子类实例也会受到影响
Parent.prototype.play.push(4);
console.log(child.play); // [1, 2, 3, 4]
这个例子中,Child
类继承了Parent
类,并且添加了自己特有的方法sayAge
。通过Object.create(Parent.prototype)
,Child
的原型指向了Parent
的一个实例,这样Child
就可以访问Parent
的原型上的属性和方法了。然后通过Child.prototype.constructor = Child
,修复了构造函数的指向,使得new Child()
能够正确返回Child
的实例。
需要注意的是,由于JavaScript中的对象属性查找是通过原型链实现的,所以如果父类的原型上的属性被修改,那么所有子类的实例都会受到影响,这就是所谓的原型链污染。因此在实际开发中,需要尽量避免直接修改原型上的属性,特别是引用类型的属性。
除了通过原型链实现继承,ES6还提供了class
和extends
关键字来更方便地实现继承。使用class
和extends
的语法糖,可以更方便地创建类和实现继承,但是底层原理仍然是基于原型链的。