JavaScript是一种基于原型的语言,这意味着对象之间的继承是通过原型链完成的。本篇博客将会详细讲解JavaScript中的原型和继承。
原型继承 在JavaScript中,每个对象都有一个链接到其原型对象的内部属性__proto__。当访问对象的某个属性时,如果在对象本身找不到该属性,则会去它的__proto__属性所指向的原型对象中查找,如果还是找不到,则会继续沿着原型链向上查找,直到最终找到该属性或者抵达原型链的顶端null为止。
我们可以通过重写一个对象的__proto__属性来继承另一个对象的属性和方法,从而实现原型继承。
示例代码:
var parent = {
name: "father",
sayHello: function() {
console.log("Hello, I'm " + this.name);
}
};
var child = {
name: "son"
};
child.__proto__ = parent;
child.sayHello(); // 输出 "Hello, I'm son"
在以上代码中,我们创建了一个父对象parent和一个子对象child,子对象通过重写自己的__proto__属性来继承父对象的属性和方法,从而实现了原型继承。
F.prototype 除了使用__proto__属性来实现原型继承外,我们也可以通过构造函数的原型来实现原型继承。每个函数都有一个prototype属性,该属性指向一个对象,这个对象就是该构造函数所创建的所有实例对象的原型对象。
我们可以通过将一个对象的__proto__属性指向构造函数的prototype属性来实现原型继承。
示例代码:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.name);
};
function Student(name) {
this.name = name;
}
Student.prototype.__proto__ = Person.prototype;
var s = new Student("Tom");
s.sayHello(); // 输出 "Hello, I'm Tom"
在以上代码中,我们通过将student对象的__proto__属性指向Person构造函数的prototype属性,从而实现原型继承。
原生的原型 JavaScript中的内置对象也有原型,例如Object、Array等。这些原型对象也可以被修改和扩展。
示例代码:
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
};
var arr = [1, 2, 3, 4, 5];
console.log(arr.sum()); // 输出 15
在以上代码中,我们给原生Array的原型对象中添加了一个sum方法,从而使得所有的数组对象都可以使用该方法。
原型方法 除了使用__proto__、F.prototype等方式来实现原型继承外,原型对象还可以用来存放公共的方法,这些方法可以被所有实例对象所继承和共享。
示例代码:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.name);
};
Person.prototype.eat = function(food) {
console.log(this.name + " is eating " + food);
};
var p1 = new Person("Jack");
var p2 = new Person("Lucy");
p1.sayHello(); // 输出 "Hello, I'm Jack"
p2.eat("cake"); // 输出 "Lucy is eating cake"
在以上代码中,我们将sayHello和eat方法添加到了Person构造函数的原型对象中,从而使得每个Person实例对象都可以使用这些方法。
没有__proto__的对象 在ES6中引入了Object.create方法,该方法可以用于创建一个新对象,并将其__proto__属性指向指定的原型对象。如果需要在较老的浏览器中使用该方法,则可以使用以下代码进行兼容:
if(typeof Object.create !== 'function') {
Object.create = function(proto) {
function F(){}
F.prototype = proto;
return new F();
}
}
示例代码:
var parent = {
name: "father",
sayHello: function() {
console.log("Hello, I'm " + this.name);
}
};
var child = Object.create(parent);
child.name = "son";
child.sayHello(); // 输出 "Hello, I'm son"
以上代码中,我们首先创建了一个父对象parent,然后使用Object.create方法创建了一个新对象child,并将其__proto__属性指向了父对象parent。最终,我们给子对象child添加了一个name属性,从而实现了原型继承。
总结:
JavaScript的原型和继承是其独特的特点之一,上述几种方法都可以用来实现原型继承。同时,其也可以用来对公共方法进行共享和继承,以提升代码的复用性和可维护性。