完全深入理解js原型链之prototype,__proto__以及constructor(二)

前言

若是你可以啃下教程一而且吃透原型链的几个概念的话说明你在前端飞仙的路上又进了一小步···学习最怕的不是慢而是站!这篇教程主要目的对原型链概念进一步加深理解html

巩固下教程一的知识

来看下面的例子:前端

var text=new String("我是文字");
function Persion(name,job){
    this.name=name;
    this.job=job;
}
Persion.myName="lxm";
Persion.prototype.sayName=function(){
    alert(this.name);
}
var perison1=new Persion("lxm","20")

思考:判断下列表达式返回的值:git

(两分钟以内对八道的算及格,剩下的同窗回头接着理解教程一,传送门在此 [http://0313.name/2017/01/13/prototype-proto-constructor.html])网络

perison1.__proto__===Persion.prototype;
perison1.name===Persion.name;
perison1.prototype.__proto__===Object.prototype;
Persion.prototype.__proto__===Object.prototype;
Persion.__proto__===Function.prototype;
Persion.constructor===perison1;
Function.__proto__===Object.prototype;
Function.prototype.__proto__===Object.prototype;
typeof Persion.prototype;
typeof Function.prototype;

原型链图

这个图绝对是网络上独一无二独一份,此乃小米飞升教程独家秘籍!由于博主在学习过程当中发现对文字的理解和记忆远远不如一个图来的更深更直观,更加透彻,为了您更好的学习原型链,博主特地花了一上午的时间用mermaid绘制了这个原型链的关系图,并且经过这个图咱们可以发现不少有意思的事情
为了关系图更加直观和清晰,隐去了一些引用线路,其中:ide

  • 圆形表明对象的名字
  • 方形表明属性名
  • 实线表明对象的分界
  • 虚线表明引用
  • 菱形表明基本值

git

  1. 原型链是单链,只往一个方向流向,没有回路函数

  2. 只有Function的proto指向本身的prototype,这也向咱们解释了为何Function.prototype类型是function
  3. 咱们经过proto只能获取到原型对象中的方法和属性,因此persion1经过原型链是获取不到Persion的myName属性,可是咱们能够经过原型对象的constructor来获取或者修改Persion的属性(这点太给力了)

请注意,有时候这个方法也很差使,由于原型对象的constructor是能够改变的,不必定指向原型对象所在的函数对象学习

继续上面的例子:this

persion1.__proto__.constructor.myName="我变了耶!";
console.log(Persion.myName); //我变了耶
  1. 普通对象的_proto__必定指向创造它的函数对象的prototype
  2. 原型对象的proto必定指向Object.prototype!
  3. 经过图咱们能够简单理解,拥有原型对象属性的对象是函数对象,不然为普通对象
  4. 原型链是有开始和尽头的,开始于null,结束于普通对象
  5. 全部的函数对象都是Function以new的方式创造出来了,包括Function本身且每一个函数对象的proto都指向了Function.prototype
  6. Object是全部对象的父类,咱们也能够称之为基类,不过不要纠结于叫什么,由于咱们经过图能够看到每个对象(不论是原型对象仍是普通对象仍是函数对象)的经过原型链均可以引向Object.prototype

以上九条我称为原型链之九句真言(不要太在乎名字,我本身随便起的 ~) prototype

意外收获:this.name和this.job难道不该该在Persion中也有一份吗?无数个日夜,愚笨的博主对this的用法都不甚了解,直到我画出了这种图,我tm完全明白了this的含义,就是谁运行包含this的这个函数,this就把挂在它身上的包袱(属性)甩给谁!
看到了吗,persion1调用了Persion,那么天然多了2个属性,可是注意,name跟job并非Persion的属性!!code

思考:图中没有画出Object.proto的指向,请问他指向哪?(请只依据九句真言解答)

思考题解答

思考:判断下列表达式返回的值:

perison1.__proto__===Persion.prototype;

首先判断perison1是经过new方式被Persion创造出来的,依据九句真言第4条得出 :true

perison1.name===Persion.name;

经过关系图能够看到不相等,我已经在乎外收获中解答了,答案为:false

perison1.prototype.__proto__===Object.prototype;

只看图能够看到perison1没有prototype,是普通对象因此答案为:js报错~~

Persion.prototype.__proto__===Object.prototype;

参考九句真言第5条:答案为:true

Persion.__proto__===Function.prototype;

Persion为函数对象,参考九句真言第8条,答案为:true

Persion.constructor===perison1;

Persion是由Function创造出来的因此Persion.constructor指向Function,答案为:false

Function.__proto__===Object.prototype;

Function咱们已经反复强调是由自身创造因此Function.proto===Function.prototype;,答案为:false

Function.prototype.__proto__===Object.prototype;

根据九句真言第5条,答案为:true

typeof Persion.prototype;

答案为:object

typeof Function.prototype;

答案为:function,注意这个是比较特殊的原型对象

思考:图中没有画出Object.proto的指向,请问他指向哪?(请只依据九句真言解答)

下面来分步解答

  1. Object属于函数对象
  2. 依据九句真言第八条得出函数对象的proto都指向了Function.prototype
  3. 因此Object.proto===Function.prototype

这一点是不太好理解的,是Function创造了Object,而后Object创造了Function的原型对象prototype
因此就有了

Object.__proto__===Function.prototype
Function.prototype.__proto__===Object.prototype

不要太纠结于此,只要理解就好

结束语

好了,原型链的概念原理经过这2篇教程我相信你们已经倒背如流了!下面的教程,咱们会着重研究下原型链在实际的应用!

做者:宜信技术学院 刘晓敏

相关文章
相关标签/搜索