返回

彻底搞懂原型(3)——原型链的应用与__proto__

前端

正文

前言

在上一节中我们了解了原型链的相关知识。那么这一节来谈谈原型链的一些具体应用和对象的非标准属性__proto__。从最常见的几种原型链的应用入手,加深大家对原型链的理解。

原型链的应用

1. 继承

继承是面向对象编程中的一个重要概念,它允许一个对象从另一个对象那里继承属性和方法。在JavaScript中,继承是通过原型链来实现的。

当一个对象被创建时,它会自动继承其构造函数的原型对象的所有属性和方法。这使得子对象能够访问和使用父对象的所有属性和方法。

例如,以下代码创建了一个名为Person的构造函数:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person构造函数有一个名为nameage的属性。

现在,我们可以使用Person构造函数来创建一个名为john的对象:

const john = new Person('John Doe', 30);

john对象会自动继承Person构造函数的原型对象的所有属性和方法。我们可以使用john对象来访问和使用这些属性和方法:

console.log(john.name); // John Doe
console.log(john.age); // 30

2. 对象的属性查找

当我们访问一个对象的属性时,JavaScript引擎会沿着原型链向上查找,直到找到该属性为止。如果在当前对象中找不到该属性,则会继续在父对象中查找,依此类推。

例如,以下代码创建一个名为person的对象,并给该对象添加一个名为name的属性:

const person = {
  name: 'John Doe',
};

现在,我们可以使用点号运算符来访问person对象的name属性:

console.log(person.name); // John Doe

如果我们尝试访问一个不存在于person对象中的属性,则JavaScript引擎会沿着原型链向上查找。例如,以下代码尝试访问person对象的age属性:

console.log(person.age); // undefined

由于person对象中没有age属性,因此JavaScript引擎会沿着原型链向上查找。但是,Person构造函数的原型对象中也没有age属性,因此JavaScript引擎最终会返回undefined

3. instanceof运算符

instanceof运算符用于测试一个对象是否是另一个对象的实例。例如,以下代码使用instanceof运算符来测试john对象是否是Person构造函数的实例:

console.log(john instanceof Person); // true

由于john对象是Person构造函数的实例,因此instanceof运算符返回true

对象的非标准属性__proto__

在JavaScript中,每个对象都有一个非标准属性__proto__。这个属性指向该对象的原型对象。

我们可以使用__proto__属性来访问和修改对象的原型对象。例如,以下代码使用__proto__属性来修改john对象的原型对象:

john.__proto__.age = 30;

现在,我们可以使用点号运算符来访问john对象的age属性:

console.log(john.age); // 30

__proto__属性是一个非常强大的属性,它允许我们动态地修改对象的原型对象。但是,我们应该谨慎使用这个属性,因为滥用这个属性可能会导致意想不到的后果。

总结

原型链是JavaScript中一个非常重要的概念。它允许对象继承其他对象