JavaScript原型,原型链 ? 有什么特点?

一、原型和原型链的比喻

想象一个家族:

  • 每个对象:像家族中的一个成员
  • 原型(prototype):家族的族谱(记录共有特征)
  • 原型链:成员通过族谱向上查找祖先的特征(比如爷爷会武术,爸爸也会,孙子也能学)

二、核心概念拆解

1. 构造函数(爸爸)
// 构造函数(像家族的爸爸)
function Person(name) {
  this.name = name;
}

// 原型对象(族谱)
Person.prototype.sayHello = function() {
  console.log(`我是${this.name}`);
};
2. 实例对象(儿子)
const 小明 = new Person("小明");
小明.sayHello(); // "我是小明" (调用原型上的方法)
3. 原型链的链接关系
  • prototype:构造函数的属性,指向原型对象(族谱)
  • __proto__(非标准,实际用 Object.getPrototypeOf()):实例的属性,指向构造函数的原型对象
  • constructor:原型对象的属性,指回构造函数

关系图

小明(实例)
  ↓ __proto__
Person.prototype(原型)
  ↓ __proto__
Object.prototype(顶级原型)
  ↓ __proto__
null(终点)

三、原型链的工作原理

1. 查找属性的过程

当访问对象的属性时,JS 会:

  1. 先检查对象自身是否有该属性
  2. 如果没有,顺着 __proto__ 向上查找原型对象
  3. 直到找到 Object.prototype,若还没有则返回 undefined

代码示例

function Person() {}
Person.prototype.skill = "武术";

const 小明 = new Person();
console.log(小明.skill); // "武术"(来自原型)
console.log(小明.toString()); // "[object Object]"(来自Object.prototype)

四、原型链的三大特点

1. 继承共享
  • 优点:所有实例共享原型上的方法,节省内存
  • 代码验证
    const 小红 = new Person("小红");
    console.log(小明.sayHello === 小红.sayHello); // true(共享同一方法)
    
2. 动态性

修改原型对象的属性,所有实例会立即生效

Person.prototype.run = function() { console.log("跑步"); };
小明.run(); // "跑步"(即使小明在修改前创建)
3. 原型链终点是 null
console.log(Object.prototype.__proto__); // null

五、手动实现原型链

场景:让「学生」继承「人」的原型
// 父类构造函数
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  console.log(`你好,我是${this.name}`);
};

// 子类构造函数
function Student(name, grade) {
  Person.call(this, name); // 继承属性
  this.grade = grade;
}

// 继承方法:将 Student 的原型指向 Person 的实例
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student; // 修复构造函数指向

// 子类扩展方法
Student.prototype.study = function() {
  console.log(`${this.name}正在学习`);
};

// 测试
const 学生小明 = new Student("小明", "六年级");
学生小明.sayHello(); // "你好,我是小明"(继承自Person)
学生小明.study();    // "小明正在学习"(自身方法)

六、常见面试问题

1. hasOwnProperty 的作用

判断属性是自身所有还是继承自原型链:

小明.hasOwnProperty("name"); // true(自身属性)
小明.hasOwnProperty("sayHello"); // false(来自原型)
2. 原型链 vs 类继承
  • 原型链:JavaScript 的底层实现方式
  • 类继承(ES6 class:语法糖,底层依然基于原型链

总结

  • 原型:对象的「族谱」,存放共享属性和方法
  • 原型链:通过 __proto__ 向上查找的链条
  • 核心价值:实现继承、共享方法、节省内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值