我们都知道,JavaScript是一种基于原型的语言,这是区别于我们大多数使用到的基于OOP的语言的,那基于原型的语言是怎样一种机制呢?其实是基于原型链,下面我们看一下原型链的机制(本文参考引用了mozilla的教程):
首先说一下原型的概念,清楚了原型的概念,才能进一步去了解原型链。先看一下Mozzila引用的代码:
var doSomeInstancing = new doSomething();
console.log( doSomeInstancing );
//打印结果:
{
__proto__: {
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
}
从代码可以看出,我们生成的对象doSomeInstancing他是有原型对象的,也就是它的__proto__属性的值,然后我们还发现它的原型对象还有自己的原型对象,也就是它的__proto__属性的__proto__属性。这就是原型对象链的结构,那这个有什么用呢?然后我们看下面的代码:
var doSomething = function(){};
console.log( doSomething.prototype );
//打印结果:
{
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
在javascript中,函数可以有属性。每个函数都有一个特殊的属性叫作原型(prototype)
我们通过new关键字,生成了doSomeInstancing这个对象,我们打印了一下这个对象的结构,发现它的__proto__属性跟它的构造函数的prototype属性是相同的!,这就是javascript原型的原理实现。
现在,假设我们要调用doSomethingInstance这个对象的某个方法,那方法是怎么去查找的,大家应该就都能想到了,首先去查找这个对象的原型对象中是否存在该方法,如果没有,就去原型对象的原型对象去查找是否存在该函数,在本例中就是Object对象,也是最后的终点。