深入理解JavaScript原型与原型链:Object与Function的关系解析

作者:纸飞机

时间:2026-10-23

浏览:279

本文深入解析JavaScript中的原型机制,阐明Object与Function的相互继承关系及函数对象与普通对象的区别。通过代码示例详细展示prototype、constructor与__proto__的作用,并完整梳理从实例到null的原型链查找过程,帮助开发者彻底理解JS对象模型。

文章目录

Object与Function的相互关系

在深入探讨JavaScript的原型机制之前,有必要先厘清Object和Function这两个核心内置对象的关系。

在JavaScript中,Object和Function均为内置构造函数。它们之间存在特殊的继承关系:Object继承自Function,而Function也继承自自身(即Function.prototype指向Function本身)。这意味着,Object和Function既具备函数的特征,也是对象实例,二者互为对方的实例。


console.log(Function instanceof Object); // true
console.log(Object instanceof Function); // true

具体而言,Object是Function的一个实例,而Function则是它自己的实例。


console.log(Function.prototype); // ƒ () { [native code] }
console.log(Object.prototype);  // Object

函数对象与普通对象的区别

接下来需要区分普通对象与函数对象的概念。

虽然JavaScript中万物皆对象,但对象内部存在显著差异,主要划分为函数对象和普通对象两类。

函数对象具备创建普通对象的能力,而普通对象无法创建函数对象。在JavaScript的对象体系中,普通对象处于基础层级,不具备特殊权限。

判断一个对象是否为函数对象的标准是:凡是通过new Function构造函数创建的对象均为函数对象,其余通过Object或字面量方式创建的多为普通对象。开发者可以使用typeof运算符来区分二者。


function f1(){};
typeof f1 //"function"


var o1 = new f1();
typeof o1 //"object"

var o2 = {};
typeof o2 //"object"

需要注意的是,以下两种函数定义方式在本质上是等价的。


function f1(){};  ==  var f1 = new Function();

function f2(a,b){
  alert(a+b);
}

等价于

var f2 = new Function(a,b,"alert(a+b)");

prototype、__proto__与constructor的关系

理解原型机制的关键在于掌握prototype、__proto__和constructor(构造函数)三者之间的关系。

以下两条核心规则对于理解原型至关重要。

第一,每个函数对象都拥有prototype属性,而普通对象通常没有该属性。

在函数的prototype属性内部,包含一个constructor属性,该属性指向函数本身。

第二,每个对象内部都隐藏着一个名为__proto__的属性(注:现代标准中建议通过Object.getPrototypeOf访问),它指向该对象所对应的构造函数的prototype。JavaScript的原型链正是基于__proto__属性构建的。

普通对象与函数对象的实例分析

通过以下代码示例,我们可以直观地观察普通对象的属性特征。

首先,普通对象o没有prototype属性。

其次,对象o是Object构造函数的实例。

第三,对象o的__proto__属性指向Object.prototype。

第四,Object.prototype.constructor属性指向Object构造函数本身。

基于上述关系,我们可以进一步延伸理解对象间的层级联系。


var o = {};
  console.log(o.prototype); //undefined
  console.log(o instanceof Object); //true
  console.log(o.__proto__ === Object.prototype) //true
  console.log(Object === Object.prototype.constructor) //true 
  console.log(Object.prototype.constructor) //function Object()
  console.log(Object.prototype.__proto__); //null

Object与Function的相互关系

通过以下函数对象的示例,可以进一步验证原型关系。

从示例可以看出,demo是函数对象,而f1是普通对象。

同时,f1是Demo构造函数的实例。

此外,demo的prototype属性的__proto__指向Object.prototype,而Object.prototype的__proto__指向null,标志着原型链的终点。


function Demo(){};
  var f1 = new Demo();
  console.log(f1.prototype); //undefined
  console.log(f1 instanceof Demo); //true
  console.log(f1.__proto__ === Demo.prototype); //true
  console.log(Demo === Demo.prototype.constructor) ;//true
  console.log(Demo.prototype.__proto__ === Object.prototype) ;//true
  console.log(Object.prototype.__proto__); //null

Object与Function的相互关系

原型链的查找机制与终点

最后,我们来详细解析原型链的工作机制。

在JavaScript中,每个对象内部都包含一个__proto__属性。当访问对象属性时,如果当前对象中不存在该属性,JavaScript引擎会沿着__proto__指向的对象继续查找,层层递进,这一过程即为JavaScript的原型链。

以f1为例,其原型链查找路径为:f1.__proto__ 指向 Demo.prototype,Demo.prototype.__proto__ 指向 Object.prototype,Object.prototype.__proto__ 指向 null。

在JavaScript中,所有事物均为对象,且均由Object衍生而来,因此所有对象的原型链终点最终都指向null。

以上关于JavaScript原型的全面讲解旨在帮助读者建立清晰的对象模型认知,供学习参考。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章