Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同
本系列作为Effective JavaScript的读书笔记。
prototype,getPropertyOf和__proto__是三个用来訪问prototype的方法。它们的命名方式非常类似因此非常easy带来困惑。
它们的使用方式例如以下:
prototype:
一般用来为一个类型建立它的原型继承对象。比方C.prototype = xxx,这样就会让使用new
C()得到的对象的原型对象为xxx。当然使用obj.prototype也可以得到obj的原型对象。
getPropertyOf:
Object.getPropertyOf(obj)是ES5中用来得到obj对象的原型对象的标准方法。
__proto__:
obj.__proto__是一个非标准的用来得到obj对象的原型对象的方法。
为了充分了解获取原型的各种方式,下面是一个样例:
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("sfalken", "0ef33ae791068ec64b502d6cb0191387");
User函数拥有一个默认的prototype属性,该属性的值是一个空对象。在以上的样例中,向prototype对象加入了两个方法,各自是toString和checkPassword。当调用User构造函数得到一个新的对象u时,它的原型对象会被自己主动赋值到User.prototype对象。即u.prototype
=== User.prototype会返回true。
User函数,User.prototype,对象u之间的关系能够表演示样例如以下:
上图中的箭头表示的是继承关系。当訪问u对象的某些属性时,会首先尝试读取u对象上的属性,假设u对象上并没有这个属性,就会查找其原型对象。
比方当调用u.checkPassword()时,由于checkPassword定义在其原型对象上,所以在u对象上不会找到该属性,查找顺序是u->
u.prototype。
前面提到过,getPrototypeOf方法是ES5中用来得到某个对象的原型对象的标准方法。因此:
Object.getPrototypeOf(u) === User.prototype; // true
在一些环境中,同一时候提供了一个非标准的__proto__属性用来得到某个对象的原型对象。当环境不提供ES5的标准方法getPrototypeOf方法时,能够临时使用该属性作为替代。能够使用以下的代码測试环境中是否支持__proto__:
u.__proto__ === User.prototype; // true
所以在JavaScript中,类的概念是由构造函数和其原型对象共同完毕的。构造函数中负责构造每一个对象特有的属性,比方上述样例中的name和password属性。而其原型对象中负责存放全部对象共同拥有的属性,比方上述样例中的checkPassword和toString方法。就像以下这张图表示的那样:
总结:
- 使用C.prototype来决定new
C()得到的对象的原型对象。 - Object.getPrototypeOf(obj)方法是ES5中提供的用于得到某个对象的原型对象的标准方法。
- obj.__proto__是获取某个对象的原型对象的非标准方法。
- 在JavaScript中,类的概念是由构造函数和其原型对象共同定义的。
Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同的更多相关文章
- 你不知道的JavaScript--Item13 理解 prototype, getPrototypeOf 和__proto__
1.深入理解prototype, getPrototypeOf和_ proto _ prototype,getPropertyOf和 _ proto _ 是三个用来访问prototype的方法.它们的 ...
- 读书笔记 effective c++ Item 30 理解内联的里里外外 (大师入场啦)
最近北京房价蹭蹭猛涨,买了房子的人心花怒放,没买的人心惊肉跳,咬牙切齿,楼主作为北漂无房一族,着实又亚历山大了一把,这些天晚上睡觉总是很难入睡,即使入睡,也是浮梦连篇,即使亚历山大,对C++的热情和追 ...
- Effective JavaScript Item 34 在prototype上保存方法
本系列作为EffectiveJavaScript的读书笔记. 不使用prototype进行JavaScript的编码是全然可行的,比如: function User(name, passwordHas ...
- Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__
本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...
- Effective JavaScript Item 10 避免使用with
本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...
随机推荐
- MySQL的truncate table 和source 命令
1. truncate table XXX 在测试时,我很讨厌某表的主键一直自增长下去,总觉得从1开始最舒服,^_^,truncate table 就可以帮我,相比delete from 来说 ...
- java操作csv文件之javacsv.jar应用
csv文件是分隔文件,如果使用java的io流来写,比较麻烦,这里为大家提供一个javacsv的jar包,这个很方便操作csv文件. 下载地址:https://pan.baidu.com/s/1i46 ...
- zepto源码研究 - zepto.js - 5(dom属性管理)
index: $.fn = {...... indexOf: emptyArray.indexOf,} index: function(element){ //这里的$(element)[0]是为了将 ...
- (七)Angularjs - 控制器
控制器的作用 没有控制器/controller,我们没有地方定义业务模型 比如:ng-init指令.我们可以使用ng-init指令在scope对象上定义数据 <div ng-init=" ...
- 武汉科技大学ACM :1008: A+B for Input-Output Practice (VIII)
Problem Description Your task is to calculate the sum of some integers. Input Input contains an inte ...
- 使用SOCKET TCP
刚刚接触SOCKET编程,网上看了一些资料,发现做些简单的应用还是不难.但是要深入了解SOCKET编程还需要系统的看一些书.一般在进程间通信TCP是一种不错的方式. ---XXX TCP链接是面向流的 ...
- epoll 中EPOLLIN 和 EPOLLOUT
epoll主要是事件回调运行的,我们使用socket的时候主要使用两个事件 EPOLLOUT事件:EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那你要先准备好下面条件:1.某次 ...
- js获取url?后的参数
function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new O ...
- 猜数字-js
var n = Math.round(Math.random()*10); //随机数 // alert(n); while(true){ var Onum = prompt('请输入1-10之间的数 ...
- 不要依赖hibernate的二级缓存
一.hibernate的二级缓存 如果开启了二级缓存,hibernate在执行任何一次查询的之后,都会把得到的结果集放到缓存中,缓存结构可以看作是一个hash table,key是数据库记录的id ...