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

相关推荐
云浪22 分钟前
前端二进制数组完全指南:ArrayBuffer、TypedArray、DataView 一次讲透
前端·javascript
铁皮饭盒1 小时前
26年bunjs, elysia+pg一把梭, redis都省了
前端·javascript·后端
kyriewen14 小时前
别再对着 TypeScript 报错发呆了:我把 10 个最常见的红色波浪线翻译成了人话
前端·javascript·typescript
free3515 小时前
从 0 实现一个 Tiny JavaScript VM:项目架构拆解
javascript
徐小夕17 小时前
我们开源了一款“框架无关”的思维导图编辑器,3分钟集成到任意系统
前端·javascript·github
PBitW17 小时前
GPT训练我的第三天,明白了应该咋说满分回答!😕😕😕
前端·javascript·面试
像我这样帅的人丶你还17 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
labixiong17 小时前
还原一个完整符合规范的 Promise(二)
前端·javascript
To_OC18 小时前
万字解析《JS 语言精粹》之第五章:继承 5 大核心精髓(JS 原型核心)
前端·javascript·代码规范
裕波19 小时前
AI 正在重写应用开发。Vue 与 Vite,给出新的答案。
javascript·vue.js