# 🌟 JavaScript原型与原型链终极指南:从Function到Object的完整闭环解析 ,深入理解JavaScript原型系统核心

深入理解JavaScript原型系统核心

📖 目录


🎯 核心概念

四大基本原则

  1. 原则一:每个对象都有构造函数(constructor)

    • 指向构建该对象或实例的函数
  2. 原则二:只有函数对象才有prototype属性

    • 非函数对象没有prototype属性
    • 实例只有__proto__属性
    • 两者指向同一个对象(函数的原型对象)
  3. 原则三:Function函数是所有函数的构造函数

    • 包括它自己
    • 代码中声明的所有函数都是Function的实例
  4. 原则四:Object也是函数

    • 所以Object也是Function函数的实例

实例,函数,对象,原型对象,构造函数,关系总览图

🔍 非函数对象分类

  • 实例对象,const person = new Foo(),person就是实例对象
  • 普通对象({}new Object()
  • 内置非函数对象实例

🔄 显式原型与隐式原型

对象分类

  • 函数对象 :拥有prototype属性
  • 非函数对象 :只有__proto__属性

相同点

  • 都指向同一个原型对象

📝 示例代码

javascript 复制代码
function Person(){}
const person = new Person();

console.log("Person.prototype指向:", Person.prototype)
console.log("person.__proto__指向", person.__proto__)

🖼️ 执行结果


🎯 构造函数的指向

默认情况

javascript 复制代码
function Person(){}
const person = new Person();

console.log("Person.prototype.constructor指向", Person.prototype.constructor)
// 输出:[Function: Person]

执行结果


修改原型对象后

javascript 复制代码
function Person(){}
const person = new Person();

Person.prototype = new foo();  // 修改原型对象

console.log("Person.prototype.constructor指向", Person.prototype.constructor)
// 输出:[Function: foo]

执行结果


📊 核心原理说明

解释

Person.prototype被当作函数foo的实例,继承了foo函数(此篇不展开继承详解)

总结规律

  • 每个原型对象或实例都有.constructor属性
  • 实例通过原型链查找constructor
  • 原型对象默认指向自身的函数(如果不是其他函数的实例)

查找过程示例

javascript 复制代码
// Person.prototype被当作实例时
Person.prototype.__proto__ → foo.prototype → foo()

🖼️ 可视化关系图

三者关系图


🔬 代码验证

javascript 复制代码
function Person(){}

// 创建新的原型对象
Person.prototype = {
    name: "杨",
    age: "18",
    histype: "sleep"
}

// 添加方法
Person.prototype.print = function(){
    console.log("你好我是原型对象");
}

// 创建实例
const person01 = new Person();
const person02 = new Person();

// 验证指向
console.log("Person.prototype指向:", Person.prototype)
console.log("person01.__proto__指向", person01.__proto__)
console.log("person02.__proto__指向", person02.__proto__)
console.log("Person.prototype.constructor指向", Person.prototype.constructor)

执行结果


⚠️ 特别说明

关键细节

创建新对象时,Person.prototype.constructor指向Object,因为Person.prototype成了Object的实例。

对比情况

  • 创建新对象时Person.prototype.constructorObject
  • 未创建新对象时Person.prototype.constructorPerson

示意图


Function和Object

小故事

从前有个力大无穷的大力神,能举起任何东西,有一天,小A在路上和这个大力神相遇了。

大力神:小子,我可是力大无穷的大力神,我能举起任何东西,你信不信?

小A:呦呦呦,还大力神,你说你能举起任何东西,那你能把你自己抬起来吗?

...

  • Function是所有函数的加工厂,你在代码声明的所有函数都是Function的实例,包括Function函数本身,Object也是函数,所以它也是Functiod的实例

  • Function就是这样的大力神,而且是可以把自己抬起来的大力神,这听起来比较扯,但是这就是事实,请看VCR:

js 复制代码
function Person (){}

const person01 = new Person();

console.log("Function.__proto__指向",Function.__proto__)//Function.__proto__指向 [Function (anonymous)] Object
console.log("Function.prototype指向",Function.prototype)//Function.prototype指向 [Function (anonymous)] Object
console.log("Function.__proto__ == Function.prototype???",Function.__proto__ == Function.prototype)
//Function.__proto__ == Function.prototype??? true

Object 在 JavaScript 中扮演三重角色:

  • 构造函数:用于创建对象

  • 命名空间:提供一系列静态方法用于对象操作

  • 原型终点:Object.prototype 是所有原型链的终点,在往上没有了,值==null

请看VCR:

js 复制代码
function Person (){};

const persoon01 = new Person();
const obj = {};//通过对象字面量{}创建obj实例
const obj1 = new Object();//通过构造函数new Object()创建obj1实例
const obj2 = Object.create(Object.prototype);//通过委托创建,或者叫原型创建,来创建obj2实例

console.log("Person.prototype.__proto__指向",Person.prototype.__proto__);
//Person.prototype.__proto__指向 [Object: null prototype] {}

console.log("Function.prototype.__proto__指向",Function.prototype.__proto__)
//Function.prototype.__proto__指向 [Object: null prototype] {}

console.log("通过对象字面量{}创建的obj实例,obj.__proto__指向",obj.__proto__);
//通过对象字面量{}创建的obj实例,obj.__proto__指向 [Object: null prototype] {}

console.log("通过构造函数new Object()创建obj1实例,指向",obj1.__proto__);
//通过构造函数new Object()创建obj1实例,指向 [Object: null prototype] {}

console.log("通过委托创建,或者叫原型创建,来创建obj2实例,指向",obj2.__proto__);
//通过委托创建,或者叫原型创建,来创建obj2实例,指向 [Object: null prototype] {}

Function和Object的关系

  • 相互依赖的循环引用
    • Object 是 Function 的实例(构造函数层面)

    • Function 是 Object 的子类(原型继承层面)

    • 这是 JavaScript 的自举(Bootstrap)机制

根据关系总览图,我们可以看到,Function和Object,它们两形成了一个闭环,将所有的函数和对象都包裹在这个闭环里

📋 JavaScript 原型系统核心概念表

概念 描述 示例 特殊说明
prototype 函数特有,指向原型对象 Person.prototype 只有函数对象才有此属性
proto 所有对象都有,指向构造函数的原型 person.__proto__ 实际应使用 Object.getPrototypeOf()
constructor 指向创建该对象的构造函数 Person.prototype.constructor 可被修改,查找时沿原型链进行
原型链查找 通过 __proto__ 逐级向上查找 person.__proto__.__proto__ 终点为 null
Function 所有函数的构造函数 Function.prototype Function.__proto__ === Function.prototype
Object 所有对象的基类 Object.prototype 原型链终点,Object.prototype.__proto__ === null

🔍 补充说明

prototype 补充

  • 函数的 prototype 属性默认包含 constructor 属性指向函数自身
  • 用于实现基于原型的继承

proto 补充

  • 现在更推荐使用 Object.getPrototypeOf(obj)Object.setPrototypeOf(obj, proto)
  • __proto__ 是访问器属性,不是数据属性

constructor 补充

  • constructor 属性可以通过原型链查找
  • 示例:person.constructor === Person(实际查找的是 person.__proto__.constructor

原型链查找补充

  • 当访问对象属性时,如果对象自身没有,会沿着原型链向上查找
  • 直到找到该属性或到达原型链终点 null

Function 补充

  • 是所有函数的构造函数,包括内置构造函数(Object、Array等)和自定义函数
  • 自身也是函数,所以 Function.__proto__ === Function.prototype

Object 补充

  • Object.prototype 是所有原型链的最终原型对象
  • 通过 Object.create(null) 可以创建没有原型的"纯净对象"

💡 记忆口诀

  • 函数看prototype,实例看__proto__
  • constructor找根源,原型链上寻答案
  • Object是终点,Function是关键

结语:

看完这篇文章,你应该可以读懂上面的关系总览图了,望学习愉快!!!

相关推荐
用户434662153132 小时前
无废话之 useState、useRef、useReducer 的使用场景与选择指南
前端
GinoWi2 小时前
HTML标签 - 表格标签
前端
氤氲息2 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
chushiyunen2 小时前
未设置X-XSS-Protection响应头安全漏洞
前端·xss
叫我詹躲躲2 小时前
别再用mixin了!Vue3自定义Hooks让逻辑复用爽到飞起
javascript·vue.js
文心快码BaiduComate2 小时前
Comate Spec模式实测:让AI编程更精准可靠
前端·后端·前端框架
菥菥爱嘻嘻2 小时前
组件测试--React Testing Library的学习
前端·学习·react.js
豆苗学前端2 小时前
HTML + CSS 终极面试全攻略(八股文 + 场景题 + 工程落地)
前端·javascript·面试
珑墨3 小时前
【迭代器】js 迭代器与可迭代对象终极详解
前端·javascript·vue.js