JS三座大山之原型链(转)

在面试时,面试官可能会通过对象的创建方式来引出原型链相关的问题:
那么创建对象的方式主要有以下几种:
第一种: 字面量
var Obj1 = {name:”o1”};
var Obj2 = new Object({name:”o2”});

第二种:构造函数
var M = function (name) { this.name = name };
var Obj3 = new M(“o3”) ;

第三种:Object.create
var p = {name:”o4”}
var Obj4 = Object.create(p);
不同的方式创建的对象略微不同。如图所示:
这里写图片描述
原型链是实现继承的主要方法,基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法。
要理解原型链就要明白原型对象、构造函数、实例,三者之间的关系。
我们先来梳理三者的关系:
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实力也有一个指向原型对象的内部指针。
当这个原型对象是另一个类型的实例,那么这个原型对象就有一个内部指针指向另一个原型,以此类推就构成了一条原型链。原型链的根就是Object.prototype。
文字描述往往没有图像描述来的直观,那么我们用一个三者之间的关系图来直观的了解。
这里写图片描述
如上图所展示的,原型对象指向构造函数的指针是 constructor ,构造函数的 prototype 指向原型对象,构造函数通过 new 操作符来创建一个实例 , 实例又可以通过内部指针 proto 指向原型对象。
proto 连接的这一条原型对象就构成了原型链。

如上面列举的创建对象方式的第二种方式,M 就是一个构造函数,那么 M 就应该有一个 原型对象,可以通过 prototype 找到!而 M 的原型对象存在 constructor,按照上图所示, M 的 原型对象的 constructor 指向的就是 M 本身;实践看结果:
这里写图片描述
上图就可以明了的证明构造函数和原型对象之间的关系;
那么我们再来看实例和原型对象的关系。依照上面的关系图,实例的内部指针 proto 指向原型对象,构造函数 M 的原型也指向同一个原型对象,究竟指向的是不是同一个原型对象呢?我们再来看:
这里写图片描述
这样两个例子就很明白的说明了实例、构造函数、原型对象三者之间的关系。
那么明白了三者之间的关系我们就来说一下原型链,从一个实例对象向上找有一个构造实例的原型对象,这个原型对象又有构造它的上一级原型对象,如此一级一级的关系链,就构成了原型链。原型链的最顶端就是Object.prototype ;

原型链最重要的作用就是继承,实例来继承上一级的属性或方法。此外,如果有多个实例,而多个实例存在共同方法,或共同属性,我们不想每一个实例都创建一份这些属性或方法,就可以将这些属性存在原型对象上,实例一样可以使用这些属性或方法;
这里写图片描述
类似于作用域链,实例在调用方法时,如果在本身没有找到,就会在原型对象上查找,如果也没有找到,就会再向上一级原型对象查找,一直找到Object.prototype ;如果中间找到会停止查找返回该方法。如果一直没找到会返回未定义;

那么,原型链就是这样的,不知道大家有没有理解。跟原型链相关的知识点还有 instanceof 运算符,还有 new 运算符,他们背后的原理也是需要研究明白的。这两个知识点我们下次再说,今天先到这里,谢谢~

你可能感兴趣的:(web)