真丶深入理解 JavaScript 原型和原型链(二):原型和原型链

原文地址: https://www.jeremyjone.com/745/,转载请注明。


上一篇文章已经总结了关于原型的两个属性,那么接下来所有原型和原型链,乃至后面的继承,都与这两个属性有关系。

原型和原型链

理解继承,首先要搞懂什么是原型和原型链。

理解原型和原型链

上面已经介绍了关于原型的两个属性:

  • __proto__
  • prototype

那么这里再小小总结一下,

1、什么是原型

原型即一个对象的构造器(prototype),可以通过该原型构造器创造无数实例,每一个实例都具有指向该原型的属性(__proto__)。

2、什么是原型链

在对象中通过原型,一层一层向上查找父级引用,直到没有父级(null)。整个这条引用链,即为原型链。原型链定义了对象可以继承的的属性/方法和相互之间的关系。

理解原型继承

有了这两个概念,尝试理解一下原型继承。

回到最开始的例子

让我们重新来看一开始那个数组的例子:

let arr = [];

我们尝试使用数组的方法:

arr.concat(["jeremyjone"]);

concat 示例

它会成功,但是我们并没有给 arr 添加 concat 的方法。它调用的是其父级 --也就是 Array 构造器-- 中的方法。

这其实就是继承。我们创建的 arr 数组实例,调用了其原型链父级的方法。

一个原型继承的例子

如果是函数呢?再来看一个例子:

function User() {
   }

这时候我们都知道这个 User 没有方法任何自己的方法。

空的User

万物都是从 Object 继承的。此时,User 也是从 Object 继承的。

那么现在给 Object 添加一个方法:

Object.prototype.print = function () {
   
  console.log("Hi jeremyjone, this is Object print.");
};
原型本身也可以继承

我们首先尝试让 User 调用这个 print 方法,要明确 User 是一个原型,但是当我们直接使用 User 的时候,它本身也是一个对象:

User 调用 Object 的 print方法

没有错,它可以被调用。这说明在原型链上,是可以找到该方法,这说明了 User 确实是从 Object 继承的。

显示User的继承关系

从图中可以看到在继承的原型中有 print 方法,即有如下等式关系:

User.__proto__.__proto__ === Object.prototype; // true
原型创建的实例来继承

同样还是刚才的例子,现在我们实例化一个 user,那么 User 现在作为一个原型,被 user 实例对象继承:

// 接上例
let user = new User();

这样得到一个 user 实例。它也可以使用其原型属性和方法。

user对象实例原型链

该 user 实例中,只有一个 __proto__ 属性,它指向了其原型,也就是 User.prototype,而其原型的父级正是 Object,即:

user.__proto__ === User.prototype; // true
user.__proto__.__proto__ === Object.prototype; // true

这个例子也印证了我们上面提到的 __proto__ 属性是作用于对象的。所以,实例和原型的 __proto__ 的值是不一样的:

user.__proto__ === User.__proto__
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值