原型对象、原型链、prototype、__proto__的理解

PS:原型的概念还是很抽象,想要一次掌握还是很困难,需要不断复习,重复理解,加深印象。多看看不同人的讲解思路,每个人的思路都不同,可以从多维度的来理解!

我也来分享一下我对原型的理解。首先要知道js中有哪几种数据类型、知道原型的作用是什么、原型是如何在对象中存在的、原型如何使用。

原型链的关键知识点:

构造函数实例(对象)FunctionObjectprototype__proto__原型链

JavaScript只有一种结构:对象

js中万物皆是对象。

出去五种基本类型以外的都是对象。

五种基本数据类型包括:String / Number / Boolean / underfine / null

剩下的Object / Function / Array 都是对象

原型链的作用

创建一个公共空间(原型对象),用来存放公共方法。

为什么需要在公共空间中存放?

  1. 如果对象中有需要使用的方法时,第一时间想到的是在构造函数中定义。但是如果需要定义许多个对象时,每个对象中都有这些方法就会占据很大的内存空间。
  2. 如果将公共方法定义在全局空间中,会污染全局变量。再多人协作开发中,函数名很可能重复,将上一个函数覆盖掉。
存储在原型对象中就可以很好的避免上述问题

原型、原型对象定义

  1. 原型(prototype):是函数的一个属性,指向原型对象
  2. 原型对象(显示原型,prototype object):是一个对象,属于所在函数的空对象,可以添加属性和方法
  3. 隐式原型(__proto__):对象中所包含的一个属性,其值由创建他得构造函数的prototype赋值,指向原型对象
  4. 所有原型对象都是Object的实例,除了Object自己的原型对象,因为Object的原型对象的__proto__为null
console.log(Person.prototype instanceof Object);  //true

原型链中的关键字:prototype和__proto__

  • prototype(显示原型):只存在于构造函数中
function Person(){
}
const fun = new Person() //Person就是构造函数
  • __proto__(隐式原型):只存在于对象中(所有对象
function Person(){
}
const fun = new Person() //Person就是构造函数
consolo.log(fun) //输出结果如下图,对象fun中有__proto__属性

在这里插入图片描述

原型链中两个特殊的对象:Function和Object

  1. Funciton对象:所有函数都是Funtino的实例,包括Funtino自己。(我new我自己)
console.log(Function.prototype === Function.__proto__);  // true
  1. Object对象:上面说到所有对象都有__proto__属性,Object也不例外,但是Object的原型对象的__proto__ 为null。
const obj = new Object()
console.log(obj.__proto__.__proto__);  //null
  1. 原型对象也是Object的实例
console.log(Function.prototype instanceof Object);  //true

终极困难

上图
在这里插入图片描述
拆分来看

在这里插入图片描述

  1. 从左到右依次代表对象、函数、原型对象
  2. 左侧创建对象,对象都含有__proto__属性,并且指向原型对象
  3. 中间为创建函数,函数都含有prototype属性,并且指向原型对象
  4. 右侧为原型对象,原型对象都含有constructor属性,并且指向构造函数
补充:
function foo(){
}
=======================
等价于
=======================
var foo = new Function()  //函数也是对象

在这里插入图片描述

  1. 从左到右依次代表对象、函数、原型对象
  2. 左侧创建对象,对象都含有__proto__属性,并且指向原型对象
  3. 中间为创建函数,函数都含有prototype属性,并且指向原型对象
  4. 右侧为原型对象,原型对象都含有constructor属性,并且指向构造函数
  5. Object的原型对象的__proto__为空(规定)

在这里插入图片描述

  1. Function是最特殊的构造函数,Object是Function的实例,就连Function自己也是自己的实例
console.log(Function.prototype === Function.__proto__);  //true
console.log(Object.__proto__ === Function.prototype);   //true

整体来看

在这里插入图片描述

  1. 所有原型对象(xxx.prototype)都是Object的实例,所以原型对象的__proto__都指向Object的原型对象
  2. 所有函数都是Function的实例(包括Object),所以构造函数的__proto__都指向Function的原型对象(Function.prototype

原型链

看懂下面这段话就基本掌握了

const A = function(){}
const a = new A()
console.log(a.__proto__ === A.prototype);   //true
console.log(A.prototype.__proto__ === Object.prototype);   //true

对象a是函数A的实例,所以a.__proto__ === A.prototype

函数A的原型对象是Object的实例,所以A.prototype.__proto__ === Object.prototype

Object的原型对象的__proto__为null

由此所以形成了一条原型链
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值