前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >JS进阶-原型链

JS进阶-原型链

作者头像
吃猫的鱼Code
发布2025-02-14 09:28:52
发布2025-02-14 09:28:52
7300
代码可运行
举报
文章被收录于专栏:吃猫的鱼个人博客编程笔记
运行总次数:0
代码可运行

原型链的定义

JavaScript 是基于 原型(prototype) 继承的语言,每个对象都可以从它的 原型 继承属性和方法。 原型链(Prototype Chain) 就是多个对象通过 prototype 关联形成的链式结构,用于实现继承。

__proto__(原型指向):实例对象内部的 __proto__ 连接到其构造函数的 prototype,形成原型链。

代码语言:javascript
代码运行次数:0
复制
实例对象.__proto__ === 构造函数.prototype

按照我自己的理解来说,就是 创建对象的那个东西长什么样子。

举个例子:有一批东西产品,是从一个模具做出来的。那这个产品 的__proto__(原型)就是这个模具,这个产品有自己的颜色和功能。(颜色可以看作这个产品自身的属性,每个都不同;功能是共享模具的,每个对象都一样)。

下面用js来深刻体会一下原型链:

代码语言:javascript
代码运行次数:0
复制
// 1 定义一个模具(构造函数)
function Product(color) {
    this.color = color; // 每个产品(实例)都有不同的颜色
}

// 2 给模具添加通用功能(方法)
Product.prototype.use = function() {
    console.log("Using the product!");
};

// 3 生产两个产品(实例)
const productA = new Product("red");
const productB = new Product("blue");

console.log(productA.color);  // "red"  (每个实例的属性不同)
console.log(productB.color);  // "blue"

productA.use();  // "Using the product!" (共享方法)
productB.use();  // "Using the product!"

console.log(productA.__proto__ === Product.prototype);  // true
console.log(productB.__proto__ === Product.prototype);  // true

另外,通过在控制台中输出一下原型,帮助理解

代码语言:javascript
代码运行次数:0
复制
function Product(color) {
    this.color = color; // 每个产品(实例)都有不同的颜色
}
Product.prototype.use = function() {
    console.log("Using the product!");
};
const p1 = new Product("red");
// 控制台输出p1原型
console.log(p1.__prodo__)
image-20250211112914168
image-20250211112914168

__proto__和prototype 是什么关系?怎么区分?

prototype:只存在于函数对象,用于定义实例共享的方法和属性

__proto__:任何对象都有,指向创建该对象的构造函数的 prototype

简单来说,它们关系如下

代码语言:javascript
代码运行次数:0
复制
// 构造函数
function Person(name) {
    this.name = name;
}

     //  通过prototype向构造函数添加方法
Person.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
};

// 实例对象
const p1 = new Person('小红');
p1.sayHello()  // Hello, my name is 小红

//简单来说
实例对象.__proto__ === 构造函数.prototype

结合上面的Person,给出下面的一些关系,供理解

代码语言:javascript
代码运行次数:0
复制
console.log(p1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

一个关系示意图是这样子的:

代码语言:javascript
代码运行次数:0
复制
p1 (实例对象)
   |
   |  __proto__
   ↓
Person.prototype (原型对象)
   |
   |  __proto__
   ↓
Object.prototype
   |
   |  __proto__
   ↓
null  (原型链终点)

深入思考——方法写在构造函数内部&&使用 prototype

经过上面,我就在想方法写在构造函数内部和使用 prototype添加,有什么区别呢?

第一种写法,把方法写在构造函数内部

代码语言:javascript
代码运行次数:0
复制
function Product(color) {
    this.color = color;

    // 每次创建一个实例,就会重新创建一个新函数
    this.use = function() {
        console.log("Using the product!");
    };
}

const p1 = new Product("red");
const p2 = new Product("blue");

console.log(p1.use === p2.use);  // false (每个实例都有自己的 use 方法,占用更多内存)

第二种写法,使用 prototype 让所有实例共享方法

代码语言:javascript
代码运行次数:0
复制
function Product(color) {
    this.color = color;
}

// use 方法只创建一次,所有实例共享
Product.prototype.use = function() {
    console.log("Using the product!");
};

const p1 = new Product("red");
const p2 = new Product("blue");

console.log(p1.use === p2.use);  // true (所有实例共享同一个 use 方法)

经查,得出结论,写在构造函数内部性能消耗严重

  • 每次 new Product(),都会创建一个新的 use 方法,导致内存浪费
  • 这些 use 方法的功能完全一样,但 JavaScript 仍然要给每个实例分配不同的函数空间。
  • 影响性能,如果创建成百上千个实例,会占用大量内存。

使用 prototype 优势:

  • use 方法只创建一次,所有 Product 实例共享这个方法。
  • 节省内存,不管有多少个实例,它们都复用同一个方法。
  • 提高性能,减少重复创建函数的开销。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025年02月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原型链的定义
  • __proto__和prototype 是什么关系?怎么区分?
  • 深入思考——方法写在构造函数内部&&使用 prototype
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档