构造函数与原型链的深入理解
2023-10-23 04:58:37
理解构造函数和原型链是学习JavaScript中面向对象编程的基础。
构造函数
构造函数是一种特殊的函数,用于创建对象。构造函数与普通函数的区别仅在于调用它们的方式不同,任何函数,只要通过new操作符来调用,那它就可以作为构造函数;任何函数,如果不通过new操作符来调用,那么它就是一个普通函数。
function Person(name, age) {
this.name = name;
this.age = age;
}
上面的代码定义了一个构造函数Person,它有两个参数:name和age。当我们使用new操作符调用Person构造函数时,它会创建一个新的对象,并将name和age参数作为该对象的属性。
const person1 = new Person('John', 30);
const person2 = new Person('Mary', 25);
上面的代码创建了两个Person对象,person1和person2。person1的name属性为'John',age属性为30;person2的name属性为'Mary',age属性为25。
原型
每个构造函数都拥有一个prototype属性,它指向一个对象。这个对象被称之为原型。原型包含了一些与该构造函数相关的方法和属性。
console.log(Person.prototype);
// 输出: {constructor: ƒ}
上面的代码输出Person的原型对象。我们可以看到,Person的原型对象只有一个属性:constructor,它指向Person构造函数本身。
原型链
原型链是一条从一个对象指向其原型的链。每个对象都有一个原型,而原型的原型又指向另一个原型,以此类推,直到最终指向null。
console.log(person1.__proto__); // 输出: Person.prototype
console.log(Person.prototype.__proto__); // 输出: Object.prototype
console.log(Object.prototype.__proto__); // 输出: null
上面的代码输出person1、Person.prototype和Object.prototype的原型对象。我们可以看到,person1的原型是Person.prototype,Person.prototype的原型是Object.prototype,而Object.prototype的原型是null。
原型链让我们能够访问父对象的方法和属性。例如,person1可以访问Person.prototype中的方法和属性,也可以访问Object.prototype中的方法和属性。
实例的属性和方法
当我们使用new操作符调用一个构造函数时,它会创建一个新的对象,并将构造函数中的属性和方法复制到该对象中。这些属性和方法被称为实例的属性和方法。
console.log(person1.name); // 输出: John
console.log(person1.age); // 输出: 30
person1.sayHello(); // 输出: Hello, my name is John
上面的代码输出person1的name属性和age属性的值,并调用person1的sayHello()方法。
原型的属性和方法
当我们访问一个对象的属性或方法时,JavaScript首先会在该对象中查找该属性或方法。如果没有找到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达null。
console.log(person1.toString()); // 输出: [object Object]
上面的代码输出person1的toString()方法。toString()方法不是person1的实例方法,而是Person.prototype的属性。因此,JavaScript会在person1中查找toString()方法,如果没有找到,则会沿着原型链向上查找,直到在Person.prototype中找到toString()方法。
总结
构造函数、原型和原型链是JavaScript中面向对象编程的基础。理解这些概念对于理解JavaScript的底层机制非常重要。