JavaScript 词条目录
前端Wiki/JavaScript/深入/原型与 this

原型与原型链

JS 的对象通过原型(prototype)共享属性和方法:访问 obj.x 时,先在对象自身找,找不到就去它的原型 __proto__ 里找,再找不到继续向上,直到 Object.prototype,最后到 null 停止——这条查找链就是原型链。数组能调用 push、字符串能调用 toUpperCase,都是因为它们的方法挂在原型上。

函数有一个特殊属性 prototype:用 new Fn() 创建的实例,其 __proto__ 正好指向 Fn.prototype。所以把公共方法挂在构造函数的 prototype 上,所有实例就能共享同一份方法,而不是每个实例复制一份——这就是 class 语法出现前的「继承」实现方式。

创建带原型的对象可以用 Object.create(proto);判断属性是自身的还是原型上的,用 hasOwnProperty。

本节要点属性查找沿原型链:自身 → 原型 → Object.prototype → null;实例的 __proto__ 指向构造函数的 prototype;公共方法挂原型实现共享。
JavaScript
const animal = {
  eat() { console.log('吃东西'); },
};

// Object.create:指定原型创建对象
const dog = Object.create(animal);
dog.name = '旺财';
dog.bark = () => console.log('汪汪');

dog.bark();   // 自身的方法
dog.eat();    // 自身没有 → 沿原型链找到 animal

// 验证原型关系
console.log(Object.getPrototypeOf(dog) === animal); // true
console.log(dog.hasOwnProperty('name'));  // true(自身属性)
console.log(dog.hasOwnProperty('eat'));   // false(原型上的)

// 构造函数 + prototype:class 出现前的写法
function Person(name) {
  this.name = name;              // 每个实例独有
}
Person.prototype.hello = function () {   // 所有实例共享
  console.log('我是' + this.name);
};
const p1 = new Person('小红');
const p2 = new Person('小刚');
p1.hello();
console.log(p1.hello === p2.hello);  // true,共享同一份方法