0

0

这么看,原型与原型链 好像也不难

coldplay.xixi

coldplay.xixi

发布时间:2020-10-22 18:30:34

|

1945人浏览过

|

来源于juejin

转载

javascript栏目简单明了介绍原型与原型链。

这么看,原型与原型链 好像也不难

         在 JavaScript 中,原型和原型链是不可避免的重要概念,那么怎么去理解原型和原型链呢?下面是我对原型和原型链的理解和总结。也许有些理解还比较浅薄,随着时间的推移和理解的深入,以后还会补充。如果大家发现我理解的有问题,欢迎大家在评论中指正。

1. 为什么 javaScript 设计为基于原型的模式

        在以往的学习过程中,我们曾通过学习面向对象语言 java 了解到其有三个要素:封装、继承、多态。关于继承,java 与 javascript 其实两者并不完全一样。
       那么 javascript 到底是如何设计出来的呢?早期,浏览器只能浏览网页内容,而不能进行用户交互,也就说当我们输入账号密码进行登录时,浏览器不能对其输入内容进行判断,需要通过服务器进行判断,而网景公司为了解决这一问题,发明一种与 java 搭配使用的辅助脚本语言,并在语法上有些类似。由此可以看出,javascript 受到 java 的影响,其都是对象类型,有对象则就会涉及到继承机制,那么JS的继承机制是怎么样呢?
        JS参考java的设计,使用new操作符生成对象,但其与java不同的是new后面跟的是 Construtor 而不是 Class 。

// java 中生成一个对象
Person p = new Person() // Person 指的是类名

// js 生成一个对象
function Person (age) {
    this.age = age
    this.nation = 'China'
}
var father = new Person(42) // Person 指的是构造函数
var mingming = new Person(11)复制代码

2. 构造函数 Constructor

        构造函数也是普通函数,其也有 prototype 属性,与普通函数的区别是其要求首字母大写。若构造函数使用new操作符调用时,其需要执行四个步骤:
       1. 创建一个新的对象
        2. 将 this 指向这个新的对象
        3. 执行构造函数,给新对象添加属性和方法
        4. 返回这个新对象

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')复制代码

3. 原型 prototype

         任何一个函数都有一个 prototype 属性,它指向 prototype 对象。那么原型其实就是一个对象,在原型上定义的属性,通过继承(new 操作符实现),实例化的对象也拥有了该属性。
        原型与构造函数的关系:构造函数内有一个 prototype 属性,通过该属性可以访问到原型。

这么看,原型与原型链 好像也不难

        以构造函数中的代码为例,Food 就是构造函数,Food.prototype 就是原型,food 就是参照 Food.prototype 生成的一个对象。

这么看,原型与原型链 好像也不难

4. 实例 instance

         实例是指一个构造函数在原型上创建可以"继承"的属性和方法,并通过new操作符创建的对象。

这么看,原型与原型链 好像也不难

         简单来说,我们使用 new 操作符创建一个 food 实例,并且可以通过 instanceof 检验实例与构造函数之间的关系。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true复制代码

         当我们在原型上定义一个属性时,实例也会"继承"这个属性。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true

// 原型定义属性
Food.prototype.type = 'object named Food'
var foodRes = food.type // 实例继承的属性
console.log(foodRes) // object named Food复制代码

5. 隐式原型 __proto__

         任何对象在创建时都会有一个 __proto__ 属性,它指向产生当前对象的构造函数的原型对象。由于该属性并非标准规定的属性,所以不要随便去更改该属性的值,以免破坏原型链。也就是说,实例可以通过 __proto__ 属性访问到原型。

这么看,原型与原型链 好像也不难

        对象中的 __proto__ 属性在所有实现中是无法访问到的,但是可以通过 isPrototypeOf() 方法来确定对象之间是否存在着这种关系。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
console.log(food.__proto__ === Food.prototype) // true
console.log(Food.prototype.isPrototypeOf(food)) // true复制代码

6. 构造函数 constructor

        构造函数可以通过 prototype 属性访问到原型,那么原型也是能够通过某种途径访问到构造函数的,其就是原型中的一个属性 constructor ,该属性并不是真正的构造函数,真正的构造函数是指 Constructor,两者不要混淆了。

phpweb1.0 美化简洁版
phpweb1.0 美化简洁版

phpweb1.0基于php+mysql+smarty开发的企业解决方案,总体感觉简洁快速,适合小型企业的建站方案,也适合初学者学习。 之前发布过phpweb1.0的原始版本,仅提供大家交流和学习,但很多的爱好者提出了一些不足和好评,本不想继续开发1.0,因为2.0已经开发完毕而且构架与1.0完全不同,但是有些使用者喜欢这种简洁和简便,应大家的要求,美化和优化了一些不足之处。后台更加简洁美观。

下载
function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')
console.log(Food.prototype.constructor === Food) //true复制代码

这么看,原型与原型链 好像也不难

        关键:prototype 的 constructor 指向构造函数本身    

        那么构造函数、原型、实例三者的关系应该是这样的:

这么看,原型与原型链 好像也不难

         为了更好地理解这一过程,我通过一个故事给大家梳理一下:
       1. 很久以前,有个雕刻家偶然看到一个很精致的花瓶(原型 Food.prototype)
       2. 一天,他想通过大批生产复刻这个花瓶来发家致富,于是他先分析这个花瓶,还原了雕刻的过程,并设计出了一条生产线(构造器 Food)
       3. 然后通过这条生产线,雕刻出许许多多的复刻花瓶。(实例 food)

7. 原型链

         proto 是任何对象都有的属性,在js中会形成一条 proto 连接起来的链条,递归访问 proto 直到值为 null ,这个搜索过程形成的链状关系就是原型链。

function Food (name) {
    this.name = name
    this.eat = function () {
        console.log('eat')
    }
}
var food = new Food('banana')  // 实例化
// 原型链
console.log(food.__proto__) // Food {}
console.log(food.__proto__.__proto__) // {}
console.log(food.__proto__.__proto__.__proto__) // null复制代码

        如下图:

这么看,原型与原型链 好像也不难

总结

        1. 每创建一个函数都会有一个 prototype 属性,该属性是一个指针,指向一个对象,该对象为原型对象(Food.prototype)。
        2. 原型对象上的默认属性 constructor 也是一个指针,指向其相关的构造函数。
       3. 通过 new 操作符产生的实例对象都会有一个内部属性指向原型对象,该实例对象可以访问原型对象上的所有属性和方法。
       4. 实例可以通过内部指针访问到原型对象,原型对象也可以通过 constructor 找到构造函数。
       5. 每个构造函数都有一个原型对象,原型对象上包含一个指向构造函数的指针,实例包含一个指向原型对象的内部指针。
       6. __proto___ 的指向取决于对象创建时的实现方式。
       7. 构造函数实例,封装的函数,如果通过 new 操作符来调用则是构造函数,否则则不是。           8. 在整个原型链上寻找某个属性,对性能有影响,越是上层的原型对象,对性能的影响越大。
       9. js中一切皆对象,通过 new Function 的是函数对象,其构造函数是 Function,而普通对象的构造函数则是 Object 。
       10. 每一个对象都有 __proto__ 属性,而每一个函数对象才有 prototype 属性。

参考来源

1.《JavaScript 高级程序设计》
2.developer.mozilla.org/zhCN/docs/W…

最后

        如果你仔细阅读完本文,相信你对 JavaScript 中的原型和原型链会有新的认识。如果你觉得对你有帮助,记得 点赞 哦!如果你发现我理解的有问题,也欢迎你在评论中指正出来。

相关免费学习推荐:javascript(视频)

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

243

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

705

2024.03.01

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

56

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

20

2025.11.27

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

579

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

20

2025.12.06

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

520

2023.06.20

2026春节习俗大全
2026春节习俗大全

本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

189

2026.02.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 4.2万人学习

Go 教程
Go 教程

共32课时 | 5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号