专栏首页编程之旅理解prototype、getPrototypeOf和_proto_之间的不同

理解prototype、getPrototypeOf和_proto_之间的不同

在学习JavaScript的过程中,原型是如何也绕不过去的一个知识点。虽然在现在ES6已经非常普及的现在,许多js的程序员都已经不再用原型的知识点来编写代码了,但是充分的理解原型也是很有必要的,尤其是在阅读他人优秀的js代码时,理解原型能帮助我们更好的理解早期代码。而原型包括三个访问器,这三个访问器有时功能重叠,所以准确的理解并区分他们还是很有必要的。

这三个访问器就是prototypegetPrototypeOf__proto__,从名字上可见这三个访问器都是对prototype这个单词做了一些变化,生成这样的属性方法名。为了测试这三个方法的输出,我们先来模拟创建一个存储用户数据User的类。

function User(name, passwordHash) {
  this.name = name;
  this.passwordHash = passwordHash;
}

User.prototype.toString = function() {
  return '[User ' + this.name + ']';
}

User.prototype.checkPassword = function(password) {
  return hash(password) === this.passwordHash;
}

这里我们创建的这个User类的构造函数,接收两个参数,一个是用户名name,一个是密码的hash值,并且类中有两个方法toString以及checkPassword用来输出用户信息和检查密码。

如果这个时候我们打印这三个原型方法的日志会得到一样的结果

var u = new User('Lix', '123456');

console.log(Object.getPrototypeOf(u)); // User { toString: [Function], checkPassword: [Function] }

console.log(u.__proto__); // User { toString: [Function], checkPassword: [Function] }

console.log(User.prototype); // User { toString: [Function], checkPassword: [Function] }

既然他们的输出都一样,那么他们是否作用一样呢,我们可以来比较测试一下。

Object.getPrototypeOf(u) === User.prototype; // true
u.__proto__ === User.prototype; // true

既然这两个方法都跟我们User对象的原型相等,那么这三个属性的区别究竟是什么呢?别急,接下来就把结论告诉大家。

  • C.prototype用于建立由 new C() 创建的对象的原型。
  • Object.getPrototype(obj)是ES5中用来获取obj对象的原型对象的标准方法。
  • obj.__proto__是获取obj对象的原型对象的非标准方法。

所以一般我们是不会直接访问C.prototype去获取原型对象的,在ES5的环境中,我们使用Object.getPrototype(obj)来获取原型对象,而在不支持ES5的环境中,我们可以考虑用__proto__这样的非标准方法来当做权宜之计,希望各位不明白的同学能牢记这些区别。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据结构——最短路径Dijkstra算法

    在上一篇博文里,我记录了最小生成树的算法实现,而在这篇里,我们来讲讲查找最短路径的算法,Dijkstra算法。

    Originalee
  • 初窥Masonry

    在早期,iPhone尺寸比较固定,都是4英寸屏幕的时候,在计算App的尺寸时,只要稍微根据Window的size稍微计算一下就可以了,但是前年iPhone6以及...

    Originalee
  • 数据结构——最小生成树(C++和Java实现)

    快要一整个月没有更新博客了,之前的几周每周都想着要写,但是最后时间还是排不开,最近的状态是一直在写代码,一直在怼工作的需求,顺便刷刷算法题,国庆则是没心没肺的玩...

    Originalee
  • SpringMVC+RestFul详细示例实战教程(实现跨域访问)

    **REST(Representational State Transfer)**,中文翻译叫“表述性状态转移”。是 Roy Thomas Fielding 在...

    好好学java
  • PDF.NET数据开发框架实体类操作实例(for PostgreSQL,并且解决自增问题) PDF.NET数据开发框架实体类操作实例(MySQL)

    本篇是 PDF.NET数据开发框架实体类操作实例(MySQL) 的姊妹篇,两者使用了同一个测试程序,不同的只是使用的类库和数据库不同,下面说说具体的使用过程。 ...

    用户1177503
  • 【DB笔试面试653】在Oracle中,请列举一次等待事件的处理案例。

    对于这道面试题而言,每个人遇到的情况不一样,答案也就不一样。只需要列举自己曾经碰到的情况,然后讲述明白即可,下面作者给出自己曾经碰到的一个案例及其处理过程。

    小麦苗DBA宝典
  • Python学习—对excel表格的操作

    py3study
  • Java 单例的五种写法

    单例的目的是为了保证某个类只实例化一个对象。对于我们来说,理解这些单例写法的不同点,最好的方法是明白他们在什么情况下会失效。

    PhoenixZheng
  • 设计模式(1)-单例模式

    单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。

    秦子帅
  • Java8的List Object 去重

    假设Object为User,此处User类中省略getting/setting以及相关构造方法。

    汐楓

扫码关注云+社区

领取腾讯云代金券