JavaScript原型链
JavaScript继承
继承一直是面向对象津津乐道的一个重要的概念。主要分为接口继承和实现继承。在JS中只有实现继承,而其中主要就是通过原型链实现的。由此,原型链有多重要就不言而喻了。
构造函数、原型、实例
先明确几个点(构造函数、原型、实例):
每个构造函数都有一个原型对象(prototype),原型对象会有一个指回构造函数的指针(constructor),每个实例都包含一个指向原型对象的内部指针(proto),构造函数通过(new)生成,
然后,什么是原型对象?什么是实例?什么是构造函数?
var Func = function (name) { this.name = name; }
var obj = new Func ('obj')
- 实例其实就是一个对象(obj)
- Func 是一个构造函数
- 实例通过(new)一个构造函数生成
上述例子中,我们可以得到这些信息。
用一段代码来展示一下
验证上述Func是构造函数
obj是实例(对象的实例),本质上还是对象
构造函数Func的prototype是原型对象
Func.prototype.constructor也就是构造函数的原型的构造函数,也就是本身
obj.constructor属性就是指的原型对象的构造函数
obj的__proto__和Func.prototype指向的是同一个原型对象(obj是通过Func new出来的)
理清楚这个关系就很清楚了
原型链
什么是原型链?
简单的理解,原型链指的就是原型对象组成的链。对象的__proto__是他的原型,他的原型同时也是一个对象,也会有__proto__属性。由此,我们可以得到一条链式的原型对象。最后当找到原型是Object的时候,原型链到头。
关于原型链其实没有说的那么神乎,只要用心去想一下其中的一些逻辑的对应的关系,也就是相当于理清楚其中的一些属性的关系就有一定的了解了
原型对象和实例之间的秘密?
通过一个构造函数,可以实例化(通过对象new对象的过程叫做实例化)多个实例。在java中,我们通常添加共有的方法是通过在构造函数中添加对应的方法,从而实现各个实例化的实例有这个方法。但是,在JS中我们有没有什么比较有意思的方法实现呢?
紧接着上面的例子,继续说说原型对象的作用
var Func = function (name) { this.name = name; }
var obj1 = new Func();
var obj2 = new Func();
obj1.__proto__.say = function(){
console.log('hello world');
}
obj1.say()
obj2.say()
用上原型,实现为每个实例添加相同的方法。
通过上述的代码,可以预见
obj1,obj2都是通过构造函数Func new出来的实例
在obj1的__proto__属性(也就是原型对象上添加了say函数)
也就是说这个函数其实就是原型对象的了(下图可见)
(按照js v8引擎的解析方式,在当前的实例本身不存在该属性时,便向他的原型中寻找对应的属性,一直往上寻找,这就是我们所说的原型链)
通过上述的几个小例子说明关于原型链的相关内容
大致对原型链应该就有一定的了解了吧
然后就是几种继承方式了