Javascript之傻傻理不清的原型链、prototype、__proto__

Javascript之傻傻理不清的原型链、prototype、__proto__

 

新人学习Javascript,其中的原型链一直是云里雾里,不得要领,查了不少相关资料,以为这遍讲得最为清晰易懂,特转载分享,共同窗习。javascript

1. JavaScript内置对象

所谓的内置对象 指的是:JavaScript自己就本身有的对象 能够直接拿来就用。例如Array String 等等。JavaScript一共有12内置对象java

其中10个函数类型( String,Number,Boolean,Array,Function,Date,RegExp,Error,Object,Event )函数类型 有 __proto__和 prototype 属性浏览器

2个对象类型(Math,JSON) 对象类型只有__proto__属性。app

下面有一张图片 由苏仔提供。函数

Javascript之傻傻理不清的原型链、prototype、__proto__

 

2. 感性认识JS里的“德罗斯特效应”之原型链

打开浏览器的控制面板,随便输入一个JS内置的构造器函数,好比Array,控制台输出的是一个名为Array的函数体,这好像并无什么稀奇的,可是,当你接着输入Array.prototype,控制面板输出了一堆咱们常常用到的Array构造器的方法,把目光转移到最下方,有一个叫__proto__的属性,好奇的点开。列表列出的不是Object构造器的方法么,里边有咱们很是熟悉的hasOwnProperty还有toString等方法。若是Array是构造器,那么控制面板输出的Array.prototype的全部属性中constructor又是什么构造器?点开看看,以后就像身处德罗斯特效应中同样,__proto__和constructor,还有Array构造器中经常使用的方法名不断的出现,一层套一层,一层层展开,没有尽头。。。学习

怎么证实 你是你?测试

拿Array举例,Array.prototype中有一个constructor属性,这个属性的值就是Array构造器本身。 因此我在console里面测试prototype

(每个构造函数都有)设计

Javascript之傻傻理不清的原型链、prototype、__proto__

 

二、“遗传进化链__proto__”,怎么证实一切皆对象?3d

全部的JS内置构造器都本是对象。但是从什么线索开始向过去前进呢,原型链(我给他起了一个名字叫遗传进化链)就是突破口。全部JS构造器(固然不止构造器有)都有一个__proto__属性,这是原型链指针,指向遗传进化成它的“那个”。它“遗传”了“那个”的特性,而又进化出了它自有的特性。

Javascript之傻傻理不清的原型链、prototype、__proto__

 

这里Array 是内置对象且是函数类型。因此Array有__proto__属性 指向的是函数类型 (function(){})。因此当咱们在输出Array.__proto__.proto__;就会返回对象类型(Object{}).可是再向上就null。由于Object就是父类了。全部的继承自Object。

JS内置构造器其中之一的Array本来就是一个函数,而这个函数就是Function的prototype,因此Function.prototype有的方法,JS内置构造器都有,好比call()、apply()、bind()等(其实咱们自定义的函数也是继承自Function.prototype,因此咱们本身也能够定义构造器)。而Function.prototype的进化链指针又指向了Object.prototype。

三、怎么证实到头来一切都是空?

Javascript之傻傻理不清的原型链、prototype、__proto__

 

四、怎么证实全部JS内置构造器和自定义函数都是Function构造器的原型(prototype)。

10个函数类型构造器的进化链指针__proto__指向Function构造器的原型.

Javascript之傻傻理不清的原型链、prototype、__proto__

 

这里须要注意全部构造器的prototype都是对象(object)类型,只有Function.prototype是函数(function)类型,这是为了保证函数构造器们的__proto__指向的都是函数。

3. JSON和Math

JS内置的构造器函数均可以使用new关键字实例化一个对象,咱们称实例化后的这个对象就是某某构造器的一个实例。就像咱们每个“人”都是“人类”这个构造器函数的一个实例。

 

Javascript之傻傻理不清的原型链、prototype、__proto__

 

咱们试试JSON 和Math 能不能实例化对象。

 

Javascript之傻傻理不清的原型链、prototype、__proto__

 

不能够。JSON和Math不是构造器函数,他们是普通的对象。

只有构造器函数才能使用new 关键字实例化一个对象,而JSON和Math已是对象了,因此咱们能够不用实例化直接使用JSON和Math中的属性和方法~~(咱们实例化的目就是想用实例化后的对象里的属性和方法,那么既然JSON和Math已是对象了,就省去实例化的操做 直接使用静态方法。

因此JSON和Math不属于10个构造器函数,但他们12个共同属于Javascript的内置对象。

4. __proto__进化链指针设计为何如此重要

javascript中为何会有__proto__原型链的设计。

先实例化一个String对象并将其赋值给str这个变量,而后咱们输出这个str

Javascript之傻傻理不清的原型链、prototype、__proto__

 

从str输出的内容来看,str有四个属性,分别是0、一、二、length。

可是 str.charAt(0); // l

str里面没有charAt()方法 可是没有报错。这是由于str的进化链上存在这个属性方法,那么charAt()这个方法在进化链的那个节点上呢。

Javascript之傻傻理不清的原型链、prototype、__proto__

 

原来String.prototype拥有charAt这个方法,而str的__proto__指针指向String.prototype。str.__proto__.__proto__指向的对象所拥有的属性str也均可以直接用

看到str.__proto__.__proto__指向的对象所拥有的属性中有一个hasOwnProperty属性方法了么,str能够直接使用这个属性方法 在验证以前先说下str.__proto__.__proto__指向了谁?指向的是Object的prototype属性。

Javascript之傻傻理不清的原型链、prototype、__proto__

 

Object.prototype.hasOwnProperty()属性方法用来检验一个对象是否本身拥有一个属性而非经过进化链__proto__继承来的属性。

Javascript之傻傻理不清的原型链、prototype、__proto__
相关文章
相关标签/搜索