JavaScript 原型相关属性详解

1. 原型链基础概念

原型(Prototype) 是 JavaScript 中实现继承和属性共享的核心机制。每个对象都有一个内部链接指向另一个对象,这个链接就是原型链。

1.1 原型链结构

复制代码
对象 → 原型 → 原型 → ... → null

2. 原型相关属性

2.1 核心属性

属性 类型 说明 示例
prototype 静态属性 仅函数对象拥有,用于定义该函数创建的对象实例的默认原型 function Foo() {}; Foo.prototype
proto 实例属性 对象实例的原型指针(已弃用,但广泛支持) obj.__proto__
constructor 实例属性 创建该对象的构造函数 obj.constructor

2.2 原型链访问方法

方法 说明 示例
Object.getPrototypeOf() 获取对象的原型(推荐使用) Object.getPrototypeOf(obj)
Object.setPrototypeOf() 设置对象的原型 Object.setPrototypeOf(obj, proto)
Object.create() 创建新对象并指定原型 Object.create(proto)

3. 详细说明

3.1 prototype 属性

仅函数对象拥有 prototype 属性,用于定义通过该函数创建的对象实例的默认原型。

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

// 在 prototype 上添加方法
Person.prototype.sayHello = function() {
  return `Hello, I'm ${this.name}`;
};

const john = new Person('John');
console.log(john.sayHello()); // "Hello, I'm John"
console.log(john.__proto__ === Person.prototype); // true

3.2 proto 属性

每个对象实例都有 proto 属性,指向其原型对象。

javascript 复制代码
const obj = {};
console.log(obj.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null

⚠️ 注意__proto__ 是历史遗留属性,虽然被广泛支持,但不是标准属性 。ES6 推荐使用 Object.getPrototypeOf() 替代。

3.3 constructor 属性

指向创建该对象的构造函数。

javascript 复制代码
function Animal() {}
const dog = new Animal();

console.log(dog.constructor === Animal); // true
console.log(dog.constructor === Object); // false

4. 原型链继承示例

javascript 复制代码
// 基类
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  return `${this.name} makes a sound`;
};

// 子类
function Dog(name, breed) {
  Animal.call(this, name); // 调用父类构造函数
  this.breed = breed;
}

// 设置原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 添加子类方法
Dog.prototype.bark = function() {
  return `${this.name} barks!`;
};

const myDog = new Dog('Buddy', 'Golden Retriever');
console.log(myDog.speak()); // "Buddy makes a sound"
console.log(myDog.bark());  // "Buddy barks!"
console.log(myDog instanceof Animal); // true
console.log(myDog instanceof Dog);    // true

5. 现代 ES6+ 替代方案

5.1 class 语法糖

javascript 复制代码
class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  
  bark() {
    return `${this.name} barks!`;
  }
}

5.2 使用 Object.create()

javascript 复制代码
const animal = {
  speak() {
    return `${this.name} makes a sound`;
  }
};

const dog = Object.create(animal);
dog.name = 'Buddy';
dog.bark = function() {
  return `${this.name} barks!`;
};

6. 原型链查找机制

当访问对象的属性时,JavaScript 会按以下顺序查找:

  1. 检查对象自身是否有该属性
  2. 如果没有,检查原型链上的原型对象
  3. 继续向上查找,直到找到属性或到达原型链末端(null)
javascript 复制代码
const obj = {};
obj.__proto__ = { sharedProp: 'I am shared' };

console.log(obj.sharedProp); // "I am shared" - 从原型链找到
console.log(obj.hasOwnProperty('sharedProp')); // false - 不是自身属性

7. 注意事项

  1. 不要直接修改内置对象的原型 (如 Object.prototypeArray.prototype),这会影响所有对象
  2. 使用 Object.create(null) 创建无原型的对象,避免继承 Object.prototype 上的方法
  3. 原型链过长会影响性能,尽量保持简洁
  4. 使用 instanceof 检查类型,它会沿着原型链查找

8. 总结

概念 说明 推荐用法
prototype 函数的原型属性 用于定义构造函数创建的对象共享的方法
proto 对象的原型指针 避免使用,用 Object.getPrototypeOf() 替代
原型链 对象之间的继承关系 理解继承机制的核心
constructor 构造函数引用 可用于类型检查或创建新实例

最佳实践 :在现代 JavaScript 开发中,优先使用 ES6 的 class 语法,它提供了更清晰的原型继承语法,同时底层仍然基于原型链实现。

相关推荐
Gofarlic_oms122 分钟前
利用API实现ANSYS许可证管理自动化集成
运维·服务器·开发语言·matlab·自动化·负载均衡
AI+程序员在路上1 小时前
VS Code 完全使用指南:下载、安装、核心功能与 内置AI 编程助手实战
开发语言·人工智能·windows·开源
invicinble2 小时前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
catchadmin2 小时前
使用 PHP TrueAsync 改造 Laravel 协程异步化的可行路径
开发语言·php·laravel
wbs_scy2 小时前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
谁呛我名字2 小时前
JavaScript 类型转换与运算规则
javascript
郑州光合科技余经理3 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
冰暮流星4 小时前
javascript事件案例-全选框案例
服务器·前端·javascript
南子北游4 小时前
Python学习(基础语法1)
开发语言·python·学习