返回

原型和原型链:洞悉 JavaScript 世界的魔法

前端

原型和原型链:JavaScript 中面向对象编程的关键概念

简介

在 JavaScript 中,每个对象都拥有一个隐藏属性——原型。原型是一个包含共享属性和方法的容器,这些属性和方法可以被对象的实例继承。通过原型链机制,对象可以访问和使用其祖先原型中的属性和方法,从而实现继承。

原型

原型是对象的隐藏属性,可以通过 Object.getPrototypeOf() 方法访问。原型存储着共享属性和方法,这些属性和方法被对象的实例继承。

const obj = {
  name: 'John',
};

const prototype = Object.getPrototypeOf(obj);
console.log(prototype); // { constructor: ƒ, __proto__: null }

上例中,prototype 是一个普通对象,具有 constructor 属性(指向对象的构造函数)和 __proto__ 属性(指向对象的原型)。

原型链

原型链是一种属性查找机制。当访问对象的属性时,JavaScript 会首先在对象本身查找。如果属性不存在,则会沿原型链向上查找。这个过程一直持续到找到属性或者到达原型链的顶端(null)。

const obj = {
  name: 'John',
};

console.log(obj.name); // 'John'

上例中,obj 对象具有 name 属性,因此 JavaScript 直接在对象本身找到了属性。

const obj = {
  getName() {
    return this.name;
  },
};

console.log(obj.getName()); // undefined

上例中,obj 对象没有 getName() 方法,因此 JavaScript 会沿原型链向上查找。由于原型链的顶端是 null,因此没有找到 getName() 方法,最终返回 undefined

继承

JavaScript 通过原型链机制实现继承。子对象可以通过 Object.create() 方法创建,该方法将父对象的原型设置为子对象的原型。

const parentObj = {
  name: 'John',
  getName() {
    return this.name;
  },
};

const childObj = Object.create(parentObj);
console.log(childObj.name); // 'John'
console.log(childObj.getName()); // 'John'

上例中,childObjparentObj 的子对象。childObj 继承了 parentObjname 属性和 getName() 方法。

应用场景

原型和原型链在 JavaScript 中广泛应用于:

  • 代码复用: 多个对象共享相同的属性和方法时,只需将这些属性和方法定义在原型中,即可被所有对象继承。
  • 函数对象: JavaScript 中的函数也是对象,因此也具有原型。函数对象的原型是一个名为 Function.prototype 的对象,它包含了一些内置方法,例如 call()apply()bind()
  • **this ** this 指向当前执行代码的对象。在对象的方法中,this 指向该对象本身。在函数中,this 指向全局对象。

总结

原型和原型链是 JavaScript 中面向对象编程的关键概念。理解原型和原型链,可以帮助我们深入理解 JavaScript 的面向对象编程机制。

常见问题解答

1. 原型是什么?

原型是对象的隐藏属性,它存储着共享属性和方法,这些属性和方法被对象的实例继承。

2. 原型链如何工作?

当访问对象的属性时,JavaScript 会首先在对象本身查找。如果属性不存在,则会沿原型链向上查找,直到找到属性或到达原型链的顶端。

3. JavaScript 中如何实现继承?

可以通过 Object.create() 方法实现继承,该方法将父对象的原型设置为子对象的原型。

4. 原型和原型链有哪些应用场景?

  • 代码复用
  • 函数对象
  • this 关键字

5. 函数对象也有原型吗?

是的,JavaScript 中的函数也是对象,因此也具有原型。函数对象的原型是一个名为 Function.prototype 的对象。