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

相关推荐
Highcharts.js6 小时前
倒置百分比堆叠面积图表示列详解|Highcharts大气成分图表代码
开发语言·信息可视化·highcharts·图表开发·面积图·图表示例·推叠图
csdn_aspnet6 小时前
C语言 Lomuto分区算法(Lomuto Partition Algorithm)
c语言·开发语言·算法
晨曦中的暮雨7 小时前
4.15腾讯 CSIG云服务产线 一面
java·开发语言
存在morning7 小时前
【GO语言开发实践】二 GO 并发快速上手
大数据·开发语言·golang
xiaoerbuyu12338 小时前
开源Java 邮箱 基于SpringBoot+Vue前后端分离的电子邮件
java·开发语言
sparEE9 小时前
c++值类别、右值引用和移动语义
开发语言·c++
zhangjw349 小时前
第11篇:Java Map集合详解,HashMap底层原理、哈希冲突、JDK1.8优化、遍历方式彻底吃透
java·开发语言·哈希算法
张元清10 小时前
useEffect 之外:专门处理异步、深比较和 SSR 的 Effect Hook
前端·javascript·面试
benpaodeDD10 小时前
视频10,11,12,13——java程序的加载与执行,安装jdk
java·开发语言
一颗牙牙10 小时前
安装mmcv
开发语言·python·深度学习