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

JavaScript 原型

JavaScript 的原型(Prototype)是其面向对象编程模型的核心概念之一,它决定了对象如何继承属性和方法。通过理解 JavaScript 的原型,你可以更好地理解对象之间的关系以及如何扩展对象功能。


核心概念

  1. [[Prototype]](内部属性)

    • 每个 JavaScript 对象都有一个隐藏的内部属性,称为 [[Prototype]]
    • 这个属性通常指向另一个对象,也就是该对象的原型。
  2. Object.prototype

    • 所有普通对象都最终继承自 Object.prototype,除非手动更改。
    • Object.prototype 是原型链的顶端,它的 [[Prototype]]null
  3. __proto__

    • 这是一些浏览器(如 Chrome 和 Firefox)中提供的访问 [[Prototype]] 的非标准方式。
    • 它主要用于调试,不推荐在实际代码中使用。
    • 现代的方式是使用 Object.getPrototypeOf(obj)Object.setPrototypeOf(obj, prototype)
  4. 构造函数与 .prototype

    • 每个函数(作为构造函数)都有一个 prototype 属性。
    • 当用构造函数创建一个对象时,该对象的 [[Prototype]] 会被设置为该构造函数的 prototype

示例

1. 创建对象与原型链
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function () {
  console.log(`Hello, my name is ${this.name}`);
};

const person1 = new Person("Alice");
person1.sayHello(); // Hello, my name is Alice

console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
2. 使用 Object.create 创建对象
const proto = {
  greet() {
    console.log("Hello!");
  },
};

const obj = Object.create(proto);
obj.greet(); // Hello!
console.log(Object.getPrototypeOf(obj) === proto); // true
3. 修改原型
function Dog(name) {
  this.name = name;
}

const dog = new Dog("Rex");

// 修改原型
Dog.prototype.bark = function () {
  console.log(`${this.name} says Woof!`);
};

dog.bark(); // Rex says Woof!

原型链

JavaScript 通过原型链实现继承。如果对象在自身没有找到属性或方法,会沿着原型链向上查找,直到顶端的 Object.prototype,若仍未找到,则返回 undefined

示例:

const obj = {};
console.log(obj.toString()); // "[object Object]" 来自 Object.prototype

原型链结构:

  • objObject.prototypenull

注意点

  1. 避免循环引用
    修改原型链时要小心,避免导致无限循环。

    const a = {};
    a.__proto__ = a; // 不推荐,可能导致错误
    
  2. 性能问题
    频繁访问深层次的原型链可能会导致性能问题。

  3. 现代方法
    使用 class 语法可以更优雅地操作原型。

    class Animal {
      speak() {
        console.log("Animal speaks");
      }
    }
    
    class Dog extends Animal {
      bark() {
        console.log("Dog barks");
      }
    }
    
    const dog = new Dog();
    dog.speak(); // Animal speaks
    dog.bark();  // Dog barks
    

http://www.kler.cn/a/400761.html

相关文章:

  • Pandas-3:数据输入与输出
  • RPA真的是人工智能吗?
  • C# 面向对象
  • python+Django+MySQL+echarts+bootstrap制作的教学质量评价系统,包括学生、老师、管理员三种角色
  • GNN初探
  • 前端基础(四十一):实时获取麦克风音量
  • golang通用后台管理系统09(系统操作日志记录)
  • MySQL —— MySQL索引介绍、索引数据结构、聚集索引和辅助索引、索引覆盖
  • C#.Net筑基-模式匹配汇总
  • 剧本杀门店预约小程序,解锁沉浸式推理体验
  • 热点更新场景,OceanBase如何实现性能优化
  • Debezium-EmbeddedEngine
  • 基于云计算的文件存储与共享平台开发
  • 创新实践:基于边缘智能+扣子的智能轮椅 AIoT 解决方案
  • CSDN如何写出”爆款“文章
  • 计算机视觉在自动驾驶汽车中的应用
  • vscode执行npm install报错
  • LeetCode35:搜索插入位置
  • LeetCode 力扣 热题 100道(五)最长回文子串(C++)
  • vue2/vue3中使用的富文本编辑器vue-quill
  • ❤React-React 组件通讯
  • Solidity 智能合约安全漏洞——普通重入攻击
  • Linux下安装mysql8.0版本
  • Debezium-MySqlConnectorTask
  • 退款成功订阅消息点击后提示订单不存在
  • 【qt】控件1