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 语法,它提供了更清晰的原型继承语法,同时底层仍然基于原型链实现。

相关推荐
Hilaku2 小时前
一周狂揽40K+ Star⭐ 的 Pretext 到底有多变态?
前端·javascript·html
533_2 小时前
适用于vue3的拖拽插件:vue-draggable-plus, vuedraggable@next
javascript·vue.js
于先生吖2 小时前
基于 SpringBoot 架构,高性能 JAVA 动漫短剧系统源码
java·开发语言·spring boot
无限进步_2 小时前
【C++&string】寻找字符串中第一个唯一字符:两种经典解法详解
开发语言·c++·git·算法·github·哈希算法·visual studio
早點睡3902 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-shadow-2
javascript·react native·react.js
xinzheng新政3 小时前
Javascript·深入学习基础知识
前端·javascript·学习
jwn9993 小时前
Laravel11.x新特性全解析
android·开发语言·php·laravel
feifeigo1233 小时前
航天器交会的分布式模型预测控制(DMPC)MATLAB实现
开发语言·分布式·matlab
于先生吖3 小时前
支持二开与商用,JAVA 漫剧付费观看系统完整源码
java·开发语言