深入理解JavaScript原型与原型链

深入理解JavaScript原型与原型链

在JavaScript中,原型(prototype)是一个核心概念,它不仅关乎对象的创建方式,还深刻影响着对象间的继承机制。本文将深入探讨原型的内涵、原型链的工作原理,以及为什么并非所有对象都拥有原型。

原型基础

每个JavaScript函数都自动配备了一个名为prototype的属性,这个属性是一个对象,用来定义当通过该函数作为构造函数创建新对象时,这些新对象(即实例)所共享的属性和方法。简而言之,原型就是构造函数创造实例的蓝图或原型模板。例如:

js 复制代码
function Person(name) {
    this.name = name;
}

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

在这个例子中,Person.prototype.sayHello定义了一个所有Person实例都可以访问的方法。

实例对象与原型的关系

当我们使用构造函数创建一个新对象时,这个新对象会自动链接到构造函数的原型对象上。这种链接是通过每个实例对象内部的特殊属性[[Prototype]](通常可访问的形式为__proto__,尽管不推荐直接使用)实现的。这意味着,实例对象可以访问其构造函数原型上的所有属性和方法,这一过程是隐式的,并且对于开发者来说是只读的。

js 复制代码
Person.prototype.like = '听歌'
function Person() {
    this.name = '田总'
}
let p = new Person()
p.like = '撸铁'

console.log(p.like); // 输出 撸铁

创建了Person的一个实例p,并为其显式地设置了一个同名属性like,值为'撸铁'。由于实例属性优先级高于原型属性,当访问p.like时,它会返回实例自身的like属性值,即'撸铁'

Constructor属性

每个实例对象都有一个constructor属性,它指向创建该实例的构造函数,这对于理解对象的来源非常有用。

js 复制代码
function Car() {
    this.name = 'su7'
}
let car = new Car()
console.log(car.Constructor);// 输出: [Function: Car]

// 实例对象通过constructor来记录我是由谁创建的

在JavaScript中,每个由构造函数创建的对象都会自动获得一个constructor属性,该属性指向创建该对象的构造函数。因此,当你打印car.constructor时,它会显示出Car构造函数本身,这表明car对象是由Car构造函数创建的。

原型链的奥秘

原型链 是JavaScript实现继承的主要机制。当访问一个对象的属性或方法时,如果该对象本身没有定义该属性或方法,JavaScript引擎会继续在其[[Prototype]]指向的对象中寻找,这个过程会一直向上追溯,直到找到该属性或方法,或者到达原型链的末端(null)。这个链式查找的过程确保了对象可以从其祖先那里继承属性和方法。

并非所有对象都有原型?

通常情况下,JavaScript中的每个对象都会有一个原型链,因为就连Object.prototype自身(所有对象原型的最终源头)也有一个null作为其原型,形成了原型链的终点。然而,有一种特殊情况:通过Object.create(null)创建的对象没有原型。这意味着该对象既没有继承自Object.prototype的默认方法(如toString()),也无法通过原型链查找机制获取任何属性或方法。这种对象常用于需要一个"纯净"对象,避免污染全局原型链的场景。

js 复制代码
let a = {
    num: 1
}

let b = Object.create(null);

这段代码在v8引擎中运行,对象a有原型,对象b由于通过Object.create(null)创建,所以该对象没有原型。

结论

原型和原型链是JavaScript实现面向对象编程和继承的核心机制。它们提供了一种灵活且高效的方式来管理对象的属性与方法,同时也允许我们通过构造函数和原型链来模拟经典的类继承模式。理解原型链的运作原理,特别是认识到并非所有对象都默认拥有原型这一特例,对于深入掌握JavaScript语言的精髓至关重要。在实际开发中,合理运用原型链,可以编写出结构清晰、易于维护的代码。

相关推荐
AI人工智能+电脑小能手5 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
红尘散仙5 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
小陈同学呦6 小时前
前端如何处理订单状态导航的数据竞态问题
前端·javascript
开发者每周简报7 小时前
网海三部曲·无名宗师传
javascript·人工智能
卷毛的技术笔记7 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
会编程的土豆7 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
Cosolar7 小时前
从零写一个 Attention Is All You Need
人工智能·面试·架构
喵个咪7 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
basketball6168 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
qq_2518364578 小时前
SpringBoot+Vue 共享电池柜管理系统 完整实现 前后端分离项目实战 完整代码
vue.js·spring boot·后端