C4 - Item 30 了解prototype,getPrototypeOf以及__proto__的区别

译文

对象(object)是Javascript的基本数据结构。直观上来说,对象表示的是一个关联字符串和值的表。但是当你深度挖掘下去,会发现有很多机制包含在对象当中。
就像很多面向对象语言一样,JavaScript提供对“实现继承”的支持:通过动态委托机制对代码和数据进行复用。但是和其他很多传统的语言不同,JavaScript的继承机制是基于原型(prototype)而非类(class)。对很多编程人员来说,JavaScript是他们遇见的第一种没有类这个概念的面向对象语言。
在很多语言中,每一个对象都其相关联的类的一个实例,而且该类为它所有的实例都提供了共享的内容。Javasript却相反,没有内建类这个概念。但是,一个对象可以继承另外一个对象。每一个对象都和一个叫做原型(prototype)的对象有关联。对原型的处理不同于对类的处理,但是传统的面向对象语言的许多概念依然延续了下来。

原型包含了三个有联系的访问器,它们的名字都由prototype这个单词变化而来。这给初学者带来了很多困惑,让我们直接划重点。

1. C.prototype用来建立通过new C()创建的对象的原型对象。
2. Object.getPrototypeOf(obj)是ES5中检索obj的原型对象的标准方法。
3. obj.__proto__是用来检索obj的原型对象的非标准方式。

想要分别理解它们,要考虑JavaScript数据类型的定义。User构造函数希望通过new操作符来创建一个能够存储名字和密码哈希值的对象。

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;
}

var u = new User("zapper","0ef33ae79");

User构造器起初伴随着一个默认的几乎为空的prototype属性。在上面的例子中,我们给User的prototype属性中加入了两个方法(toString和checkPassword)。当我们通过new创建User的实例的时候,它的实例u就把User.prototype对象自动设为了它的prototype对象。

实例对象u和User.prototype之间表现的就是继承关系。u的属性查找就是先从自己当前的属性开始找起(如name属性和passwordHash属性)。属性没有直接被找到,就会从prototype中去寻找。调用u.checkPassword方法,就是从prototype中找到的。

虽然prototype属性用来给构造器建立实例的的prototype关系,但是ES5中的Object.getPrototypeOf()方法可以获取一个已经存在的实例对象的prototype对象:

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

一些运行环境下为获取实例对象的prototype提供了非标准的__proto__方法。这是不支持ES5的Object.getPrototypeOf()方法的环境下的权宜之计。在这样的环境下可以进行测试:

u.__proto__ === User.prototype; //true

最后需要注意的一点是,很多JavaScript程序员经常将User描述成类,即使仅仅是因为它比一个构造器更加强大。但是本质上来说,JavaScript中类的概念是联合了构造器本身以及原型对象存在的。


Things to remember

1. 在JavaScript中,类是一种包含构造器和原型对象的设计模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值