原型是什么?
在Java中,对象会从类中继承属性,方法等,但JavaScript中并没有类的概念,JavaScript中的对象从原型对象中继承属性,方法。(虽然在ES6中引入class关键字,但本质上是一种‘语法糖’,并不是真正意义上的类概念)。
一个‘神奇’的现象
我们先定义一个构造器(函数):
function People(a,b,c){
this.height = a;
this.weight = b;
this.age = c;
}
对于构造器,访问属性prototype可以获得它的原型对象:
console.log(People.prototype);
在浏览器控制台中会显示:

这就是它的原型对象。
如果点开constructor,会发现里面有里面包含proto属性(并不是上图中的proto,而是constructor中的proto),再点开proto会出现‘套娃’的情况:

又出现了constructor,再点开constructor里面还有proto属性,这么一直点下去是无穷无尽的……
其中的proto属性,指向一个对象的构造函数的原型。
其实归根结底,原因就一个式子:
构造器(函数)的原型对象(prototype)的构造器(constructor)就是函数本身
结合上面的构造函数就是:People == People.prototype.constructor
(也就是说一直点开下拉菜单相当于不停轮流访问prototype和constructor属性,所以是无穷无尽的)
原型对象
说回原型,原型是个很抽象的概念,因为我们并不能看到它。当定义了一个构造器的时候,就会产生一个原型对象。这个构造器所构造的对象,都会从原型对象中继承到属性,方法等,我们定义一个小明‘xiaoming’对象,并打印出来:
var xiaoming = new People(170,60,18);
console.log(xiaoming);
在控制台可以看到:

检查小明对象的proto属性,也就是小明对象的构造器的原型对象,我们会发现它实际上就是上面我们看过的People构造器的原型对象(People.prototype)。
那么什么是原型链呢?
其实理解了原型,就很好理解原型链了,我们发现小明对象继承自People构造器的原型对象,而People构造器的原型对象又是从哪继承的呢?上图中最后一行proto,也就是
__proto__:Object
它就是JavaScript中的object(对象)的构造函数,点开它会发现它不再拥有proto属性了,也就是它的proto属性是null,这就说明寻找构造函数到头了,这就是所谓的原型链的终点。
事实上,随便定义一个对象:
var xiaohei = {
height:180,
weight:80,
age:20
}
然后去控制台打印出来:
console.log(xiaohei);
会显示:

它并没有一个构造函数,它的原型对象的构造函数就是object构造函数,事实上在JavaScript中不管什么对象,只要顺着它的proto属性往上寻找,就必然会回到object构造函数,也就是说JavaScript中任何对象都是object的实例。这就是原型链。
这篇文章比我说的牛批多了,没看明白的去看这个吧:(得,讲了半天不如给个链接)
https://juejin.im/post/5d713de26fb9a06ad3474c15
文章里面可能有错误,如果有读者看到希望能指出
网友评论