面试之《原型与原型链》

在 JavaScript 中,原型(Prototype)原型链(Prototype Chain) 是实现对象继承和属性共享的核心机制。以下是详细介绍:

一、原型(Prototype)

  1. 基本概念

    • 每个函数(包括构造函数)都有一个 prototype 属性,指向一个对象,称为原型对象
    • 当使用 new 调用构造函数创建实例时,实例内部会有一个隐藏属性 __proto__(ES6 规范中称为 [[Prototype]]),指向构造函数的原型对象。
    • 原型对象的作用是为所有实例共享属性和方法,避免重复定义。
  2. 示例

    javascript 复制代码
    function Person(name) {
      this.name = name;
    }
    
    // 原型对象添加方法
    Person.prototype.sayHello = function() {
      console.log(`Hello, ${this.name}`);
    };
    
    const person = new Person("Alice");
    console.log(person.__proto__ === Person.prototype); // true
    person.sayHello(); // Hello, Alice

二、原型链(Prototype Chain)

  1. 基本概念

    • 每个对象(包括原型对象)都有自己的 __proto__,指向其"父级"原型对象,形成一条链式结构,称为原型链
    • 当访问对象的属性或方法时,JavaScript 会沿着原型链向上查找,直到找到目标属性或到达 null(终点)。
  2. 原型链结构

    复制代码
    Object.prototype ← Function.prototype ← ... ← 自定义原型 ← 实例
    • 所有对象的最终原型是 Object.prototype,它定义了 toString()valueOf() 等通用方法。
    • 函数的原型是 Function.prototype,而 Function.prototype 的原型是 Object.prototype
  3. 示例

    javascript 复制代码
    const obj = {};
    console.log(obj.toString()); // 来自 Object.prototype
    console.log(obj.hasOwnProperty("toString")); // false(属于原型链)

三、关键特性

  1. 属性查找规则

    • 优先查找对象自身的属性,若不存在则沿原型链向上查找。
    • 修改对象自身的属性会直接覆盖原型链中的同名属性。
  2. 原型链的继承

    • 通过修改原型对象,可以实现类似"继承"的效果。例如:

      javascript 复制代码
      function Animal() {}
      Animal.prototype.eat = function() { console.log("Eating..."); };
      
      function Dog() {}
      Dog.prototype = Object.create(Animal.prototype); // Dog 的原型链继承 Animal
      Dog.prototype.bark = function() { console.log("Woof!"); };
      
      const dog = new Dog();
      dog.eat(); // 继承自动物原型
      dog.bark(); // 自身方法
  3. 原型链的终点

    • Object.prototype.__proto__ 的值为 null,表示原型链的结束。

四、相关方法

  1. isPrototypeOf()

    检查一个对象是否是另一个对象的原型:

    javascript 复制代码
    console.log(Animal.prototype.isPrototypeOf(dog)); // true
  2. hasOwnProperty()

    判断属性是否是对象自身的属性(而非原型链中的属性):

    javascript 复制代码
    console.log(dog.hasOwnProperty("bark")); // true
  3. Object.getPrototypeOf()

    获取对象的原型(ES6 方法,替代 __proto__):

    javascript 复制代码
    console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true

五、注意事项

  • 避免原型链过长:过长的原型链会影响属性查找性能。
  • 原型与实例的动态关联:修改原型对象会影响所有后续创建的实例,但已存在的实例不会受影响。
  • class 语法糖 :ES6 的 class 本质上仍基于原型链,只是语法糖简化了实现。

总结

  • 原型是对象共享属性和方法的基础。
  • 原型链 通过 __proto__ 连接对象,实现属性的继承和查找。
  • 理解原型链有助于掌握 JavaScript 的核心机制(如继承、多态),并避免常见错误。
相关推荐
veneno8 小时前
大量异步并发请求控制并发解决方案
前端
i***t9198 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
oden8 小时前
2025博客框架选择指南:Hugo、Astro、Hexo该选哪个?
前端·html
小光学长9 小时前
基于ssm的宠物交易系统的设计与实现850mb48h(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·前端·数据库
小小前端要继续努力9 小时前
渐进增强、优雅降级及现代Web开发技术详解
前端
老前端的功夫10 小时前
前端技术选型的理性之道:构建可量化的ROI评估模型
前端·javascript·人工智能·ubuntu·前端框架
狮子座的男孩10 小时前
js函数高级:04、详解执行上下文与执行上下文栈(变量提升与函数提升、执行上下文、执行上下文栈)及相关面试题
前端·javascript·经验分享·变量提升与函数提升·执行上下文·执行上下文栈·相关面试题
许强0xq10 小时前
Q19: fallback 和 receive 有什么区别?
面试·web3·区块链·solidity·以太坊·evm
爱学习的程序媛10 小时前
《JavaScript权威指南》核心知识点梳理
开发语言·前端·javascript·ecmascript
乐观主义现代人11 小时前
go 面试
java·前端·javascript