JavaScript原型与原型链:深入浅出指南

JavaScript原型与原型链:深入浅出指南

本文通过代码实例和通俗解释,带你彻底理解JavaScript中最核心的概念之一

什么是原型?

在JavaScript中,原型(Prototype) 是函数天生拥有的一个属性(prototype),它是一个对象,用于存放可以被所有实例共享的属性和方法。

ini 复制代码
// 定义构造函数
function Car(color) {
  this.color = color;
}

// 在原型上添加共享属性
Car.prototype.name = 'su7-Ultra';
Car.prototype.height = 1.4;

const car1 = new Car('orange');
const car2 = new Car('green');

console.log(car1.name); // 'su7-Ultra'(来自原型)
console.log(car2.height); // 1.4(来自原型)

原型存在的意义

  1. 将构造函数中固定的属性和方法挂载到原型上
  2. 实例创建时无需重复执行这些属性和方法
  3. 节省内存,提高性能

对象原型(隐式原型)

每个对象都有一个内置属性 __proto__(隐式原型),它的值指向创建该对象的构造函数的原型(prototype)。

ini 复制代码
function Person(name) {
  this.name = name;
}

const p1 = new Person('超超');

console.log(p1.__proto__ === Person.prototype); // true

关键概念 :实例对象的隐式原型(__proto__)等于构造函数的显示原型(prototype

new关键字的内部原理

当使用 new 调用构造函数时,会发生以下步骤:

kotlin 复制代码
function _new(constructor, ...args) {
  // 1. 创建一个空对象
  const obj = {};
  
  // 2. 将构造函数的this指向这个空对象
  // 3. 执行构造函数中的代码
  constructor.apply(obj, args);
  
  // 4. 将空对象的隐式原型指向构造函数的原型
  obj.__proto__ = constructor.prototype;
  
  // 5. 返回这个对象
  return obj;
}

// 实际使用
const car = _new(Car, 'blue');

原型链:JavaScript的继承机制

当访问对象的属性时,JavaScript引擎会:

  1. 先在对象自身属性中查找
  2. 如果找不到,则沿着 __proto__ 向上查找
  3. 直到找到 null 为止

这种查找路径形成的链条就是原型链

ini 复制代码
function GrandParent() {
  this.name = 'grandparent';
}

function Parent() {
  this.lastName = '张';
}

function Child() {
  this.firstName = '三';
}

// 设置原型链
Parent.prototype = new GrandParent();
Child.prototype = new Parent();

const child = new Child();

console.log(child.name); // 'grandparent'(来自GrandParent)
console.log(child.lastName); // '张'(来自Parent)

原型链的终点

所有原型链的终点都是 Object.prototype,而 Object.prototype.__proto__null

javascript 复制代码
console.log(Object.prototype.__proto__); // null

没有原型的对象

使用 Object.create() 可以创建没有原型的对象:

javascript 复制代码
const obj = Object.create(null); // 没有原型的对象
console.log(obj.toString); // undefined(没有继承Object的方法)

实际应用:数组方法

为什么我们创建的空数组可以直接使用 push()pop() 等方法?

javascript 复制代码
const arr = []; // 相当于 const arr = new Array()

console.log(arr.__proto__ === Array.prototype); // true
console.log(Array.prototype.hasOwnProperty('push')); // true

数组的所有方法都存在于 Array.prototype 中,所以所有数组实例都可以访问这些方法。

总结:原型与原型链要点

概念 描述 示例
prototype 函数特有的属性,存放共享方法 Car.prototype.run = function(){}
__proto__ 对象特有的属性,指向其原型 car.__proto__ === Car.prototype
原型链 通过 __proto__ 连接的链条 child -> Parent.prototype -> GrandParent.prototype -> Object.prototype -> null
属性查找 沿原型链向上查找属性 child.name 查找过程
constructor 指向创建对象的构造函数 car.constructor === Car

理解原型和原型链是掌握JavaScript面向对象编程的核心。通过原型,JavaScript实现了高效的属性共享和继承机制,这也是JavaScript区别于传统面向对象语言的重要特点。

相关推荐
2401_8949155338 分钟前
GEO 优化源码全解析:从搜索引擎到 AI 引擎的底层改写逻辑
java·服务器·前端·数据库·人工智能·分布式·搜索引擎
rockey6275 小时前
C#脚本引擎之AScript与Jurassic、Jint对比
javascript·c#·.net·js·script·动态脚本
Profile排查笔记6 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
lzhdim6 小时前
12、JavaScript常见的内存泄露问题 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
denggun123456 小时前
yield
前端·数据库·python
前端snow6 小时前
ai agent -- prompt汇总
前端
muddjsv8 小时前
前端性能优化实战:从加载到渲染的全面提速指南
前端·性能优化
deli0070078 小时前
JSON 树形查看器:粘贴即解析,折叠展开一目了然
前端·数据库·json·ai编程
guanguan0_09 小时前
PageProxy:页面维度接口地图 + 一键场景切换
前端·ai编程·请求代理·proxy工具
liangshanbo12159 小时前
虚拟列表深度面试题整理
java·开发语言·前端