JS原型链详解(2)
深入理解javascript原型链
在javascript中原型和原型链是一个很神奇的东西,对于大多数人也是最难理解的一部分,掌握原型和原型链的本质是javascript进阶的重要一环。今天我分享一下我对javascript原型和原型链的理解。
一、对象等级划分
我们认为在javascript任何值或变量都是对象,但是我还需要将javascript中的对象分为一下几个等级。
首先Object是顶级公民,这个应该毋庸置疑,因为所有的对象都是间接或直接的通过它衍生的。Function是一等公民,下面会做解释。几个像String,Array,Date,Number,Boolean,Math等内建对象是二等公民。剩下的则都是低级公民。
二、原型prototype
首先prototype是一个属性,同时它本身也是一个对象。那么哪些是具有prototype这个属性呢?其实javascript中所有的函数都有prototype这个属性,反过来所有具有prototype的对象本身也是一个函数,没错就是一个函数。
第一条我不再印证,主要看看第二条。大家都知道Object,Array,Date都有prototype,他们是函数吗?是的他们也是函数的一种,为什么这么说呢?我们在定义一个对象或者数组时,是不是可以这么做var o = new Object(),a = new Array()。学过java的人都知道new是用实例化一个对象的方法,但是我们都知道javascript中不存在真正的类的概念,所以只能用函数来模拟,那么既然可以有上面的做法也就印证了Object和Array也是特殊的函数。
其实上面说到的几等公民基本都是函数的一种,除了Math这个工具对象外,应该没有见过这种new Math()这种写法吧!当然这种写法也是会报错的,所以在访问Math.prototype返回的也是undefined。
三、__proto__和原型链
__proto__是一个指针,它指的是构造它的对象的对象的prototype,听起来有的拗口。举个例子吧!
如上面代码,o是Object的一个实例,所以o的__proto__指针指向构造o的Object的prototype。这样的意义在于o可以使用Object.prototype里面的方法,例如toString(),o在访问toString方法时,首先会在自身寻找,如果没有找到则会在__proto__也就是Object.prototype上面查找。
可以说几乎所有的javascript对象都有__proto__这样一个指针包括Object,我们来看一看
其实a = 1就相当于a = new Number(1)。可以看到所有的内建对象以及Object的__proto__指向的都是一个匿名函数,也就可以认为它们其实也是function的一个实例,所以之前会说function是一等公民。
那么原型链到底是什么呢?我们展开a.__proto__也就是Number.prototype对象,它是没有toString()的方法的,但是对于a来说它其实是可以调用toString的方法的,这就是原型链的作用。看下面代码
看上面代码和结果,我们沿着a的__proto__一直访问会到达Object的prototype,也就是说a调用toString方法最终其实是访问Object.prototype的toString方法。那么a的原型链就是由Number.prototype和Object.prototype组成,当a访问一个方法或属性时,它会先在自身查找,然后再沿原型链找,找到则调用,没找到报错。为了印证这一点,我们在Number.prototype上面加一个toString的方法。
可以看到a调用的是Number.prototype的toString方法,在找到之后就停止。在javascript中,几乎所有的对象的原型链的终点都是Object.prototype
总结
__proto__是实现原型链的关键,而prototype则是原型链的组成。最后附上一张稍微复杂的原型链和构造函数的关系图,有兴趣可以研究一下。
最新文章
- jquery.mobile手机网页简要
- JS限制input输入的为数字并且有小数的时候最多保留两位小数
- JDK和IDE
- Servlet过滤器,Servlet过滤器创建和配置
- 序列sequence中的cache问题
- ExcelHelper
- OC-点语法
- JS日期加减,日期运算
- Node 实现 AES 加密,结果输出为“byte”。
- SpringJUnit4加载类目录下(src)和WEF-INF目录下的配置文件二--获取注入的bean的二种方式
- web前端开发中Nodejs、Grunt、npm等的介绍、使用
- BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
- Patch to solve sqlite3_int64 error when building Python 2.7.3 on RHEL/CentOS
- delphi 关键字
- tableView左滑按钮
- 四大组件之一---------activity的知识
- 在windows系统下安装linux虚拟机(VMware)
- OpenStack 命令行速查表
- Azure WebJob-Custom Schedule for Azure Web Job Timer Triggers
- C# Window Service安装、卸载、恢复选项操作
热门文章
- webstorm tools window
- vue2.0 之 douban (四)创建Swipe图片轮播组件
- z-index的各种坑
- 002-localStorage和sessionStorage操作
- 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_16_常用的函数式接口_Function接口中练习-自定义函数模型拼接
- Newtonsoft.Json源码中的C#预处理指令
- kNN算法实例(约会对象喜好预测和手写识别)
- 四种pop模式介绍
- python基础-5.1几种常见的排序算法
- Webpack基础学习