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.prototype、Array.prototype),这会影响所有对象
  2. 使用 Object.create(null) 创建无原型的对象,避免继承 Object.prototype 上的方法
  3. 原型链过长会影响性能,尽量保持简洁
  4. 使用 instanceof 检查类型,它会沿着原型链查找

8. 总结

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

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

相关推荐
1024奇点6 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch6 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
Knight_AL7 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing038 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿8 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
by209998 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河8 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
IT召唤狮8 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻8 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble8 小时前
C++ 用互斥锁实现读写锁
开发语言·c++