当前位置: 首页 > news >正文

前端知识点---原型-原型链(javascript)

文章目录

  • 原型
  • 原型链:
  • 实际应用
  • 面试题回答

原型

原型:每个函数都有prototype属性 称之为原型

因为这个属性的值是个对象,也称为原型对象

只有函数才有prototype属性

作用:
1.存放一些属性和方法
2.在Javascript中实现继承

const arr = new Array(1, 2, 3, 4)
console.log(arr.reverse)

为什么创建好了就可以使用这些方法呢? 就是原型的存在

Array构造函数也是一个函数 , 只要是函数就有个原型 就是Array.prototype

打开mdn
在这里插入图片描述
在这个原型身上已经挂载了很多方法, 这些方法是可以给所有的数组实例去使用的

为什么实例可以去使用这些方法呢 , 是因为_porto_

每个对象都有_proto_属性

作用: 这个属性指向它的原型对象
在这里插入图片描述

原型链:

在这里插入图片描述

关系总结:

构造函数 -> prototype -> 构造函数的原型对象
构造函数的原型对象 -> proto -> Object.prototype
Object.prototype -> proto -> null(原型链的终点)
代码演示:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const p = new Person("张三", 25);

// p 的 __proto__ 指向 Person.prototype
console.log(p.__proto__ === Person.prototype); // true

// Person.prototype 的 __proto__ 指向 Object.prototype
console.log(Person.prototype.__proto__ === Object.prototype); // true

// Object.prototype 是原型链的终点
console.log(Object.prototype.__proto__); // null

解释:
Person.prototype.proto 确实指向 Object.prototype。
Object.prototype 没有更上层的原型,所以它的 proto 是 null。

所以,构造函数的原型对象最终的 proto 是指向 Object.prototype,而 Object.prototype 的 proto 是 null,这是原型链的终点。

实际应用

  1. 共享方法,减少内存开销
    在大型项目中,如果每个实例都独立创建相同的方法,会占用大量内存。原型可以让多个实例共享方法,从而提高性能。

示例:创建对象的优化

function User(name) {
    this.name = name;
}

// 将方法放在 prototype 上,所有实例共享
User.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
};

let user1 = new User("Alice");
let user2 = new User("Bob");

user1.sayHello(); // 输出: Hello, my name is Alice
user2.sayHello(); // 输出: Hello, my name is Bob

✅ 优点:所有 User 实例共享 sayHello 方法,而不是每次创建实例都生成新的方法,节省内存。

  1. 继承与扩展
    在项目中,多个对象可能有相似的行为,我们可以利用原型继承来减少代码重复,提高复用性。

示例:父类与子类继承

function Animal(name) {
    this.name = name;
}

// 父类原型方法
Animal.prototype.speak = function() {
    console.log(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() {
    console.log(this.name + " barks!");
};

let dog1 = new Dog("Buddy", "Labrador");
dog1.speak(); // 输出: Buddy makes a sound
dog1.bark();  // 输出: Buddy barks!

✅ 优点:

Dog 继承了 Animal 的 speak 方法,无需重复定义。
Dog.prototype 还能额外扩展 bark 方法,增强灵活性。
3. 扩展原生对象
有时候我们需要扩展 JavaScript 自带的对象,比如 Array、String 等。

示例:扩展 Array.prototype

Array.prototype.sum = function() {
    return this.reduce((total, num) => total + num, 0);
};

let numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // 输出: 15

✅ 优点:给所有数组对象增加 sum 方法,方便项目中复用。

⚠️ 注意:扩展原生对象可能会影响第三方库,应谨慎使用!

  1. 实现类的私有属性
    在 ES5 时代,我们可以通过原型和闭包结合,模拟私有变量,防止外部直接访问。

示例:使用闭包模拟私有属性

function Person(name) {
    let _age = 25; // 私有变量,外部无法直接访问
    this.name = name;

    this.getAge = function() {
        return _age;
    };
}

let p1 = new Person("Alice");
console.log(p1.name);  // Alice
console.log(p1.getAge()); // 25
console.log(p1._age);  // undefined,无法直接访问

✅ 优点:保护 _age 变量不被外部随意修改,提高安全性。

  1. 结合原型模式和单例模式
    在实际开发中,我们可能希望某个对象只存在一个实例(比如配置管理、数据库连接池等)。可以结合原型模式和单例模式来实现。

示例:全局配置管理

const Config = (function() {
    function Config() {
        this.theme = "dark";
        this.language = "en";
    }

    let instance;
    
    Config.getInstance = function() {
        if (!instance) {
            instance = new Config();
        }
        return instance;
    };

    return Config;
})();

let config1 = Config.getInstance();
let config2 = Config.getInstance();

console.log(config1 === config2); // true,说明是同一个实例

✅ 优点:

只创建一个 Config 实例,避免重复初始化配置,提高效率。
总结

应用场景代码示例主要作用
方法共享User.prototype.sayHello让多个实例共享方法,节省内存
继承与扩展Dog.prototype = Object.create(Animal.prototype)复用父类方法,减少代码重复
扩展原生对象Array.prototype.sum添加全局通用方法,增强功能
私有属性let _age = 25;保护数据,防止外部修改
单例模式Config.getInstance()确保对象全局唯一

在实际项目中,合理运用原型能有效提高代码复用性、减少冗余,并优化性能! 🚀

面试题回答

  • 1.原型:函数都有prototype属性,称之为原型,也称为原型对象N原型可以放一些属性和方法,共享给实例对象使用
    原型可以做继承
  • 2.原型链:对象都有_proto 属性,这个属性指向它的原型对象,原型对象也是对象,也有_proto 属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链,最顶层找不到则返回 null

相关文章:

  • 【鸿蒙开发】Hi3861学习笔记-Visual Studio Code安装(New)
  • matlab 模糊pid实现温度控制
  • Java 常用工具类大全:高频工具类及代码示例(后续继续补充)
  • 大模型最新面试题系列:微调篇之微调基础知识
  • 使用 Elasticsearch 构建多模式 RAG 系统:哥谭市的故事
  • 【SpringMVC】常用注解:@MatrixVariable
  • C 语言实战:打造字符串加密器及实验要点解析
  • leetcode 3305. 元音辅音字符串计数 I 中等
  • Ubuntu从源代码编译安装QT
  • Git 的基本概念和使用方式
  • 网络安全就业形势
  • AGI大模型(6):提示词模型进阶
  • 【软考-架构】11.3、设计模式-新
  • C#中SerialPort 的使用
  • LabVIEW VI Scripting随机数波形图自动生成
  • MySQL的一些八股文
  • 上位机数据可视化:Qt表格美化
  • VSTO(C#)Excel开发10:启动和卸载顺序 事件处理 监视变化
  • A SURVEY ON POST-TRAINING OF LARGE LANGUAGE MODELS——大型语言模型的训练后优化综述——第2部分
  • Java8计算集合属性的最大值
  • 怎么样从头开始做网站/网站推广怎样做
  • 衡阳房产网/seo营销方案
  • 武汉微网站/宣传推广计划怎么写
  • wordpress 最新文章展示/seo外包是什么
  • 平凉网站设计/哈尔滨优化网站公司
  • crm系统公司有哪些/廊坊seo建站