如果在搞不懂javaScript的原型和原型链,我就锤自己了!
首先在javaScript中,原型对象和对象是什么关系呢?
在javaScript中,不管是对象,还是函数和数组,它们都是Object的实例,除了原形类型以外。其余的都是对象。所以在javaScript中,函数也是一个特殊的对象,他也同样拥有属性和值,而所有函数都会有一个特别的属性prototype,prototype这个属性的值是一个对象,这个对象就是我们常说的 “原型对象”
我们在这打印一下这个实例
function Person(name){
this.name=name;
}
console.log(Person.prototype);
打印出来的结果为这个
那这打印的 __proto__ 和 constructor 又是什么呢?他跟 __proto__ 和 prototype 又有什么区别呢?
首先我们必须知道,prototype属性是函数独有的!该属性为该函数的原型对象,所以它是由一个函数指向另一个对象。而__proto__属性是对象所独有的.(通过上面的代码段我们也知道,prototypt也是对象属性),所以它是由一个对象指向另一个对象.
然后在默认的情况下,所有函数的原型对象(prototype)都拥有constructor属性,该属性指向与之关联的构造函数,在上面的实例里构造函数便是Person函数,而Person函数的原型对象(prototype)同样拥有自己的原型对象用__propt__属性表示,因此Person.prototype的原型对象为Object.prototype。
可以用下面的图来表示,这样可以理解的更清楚
所以我们可以用prototype和__proto__来实现继承
通过对象A的__proto__属性赋值为b对象B
即A.__proto__ = B
此时使用A.__proto__便可以访问B的属性和方法
javaScript 可以在两个对象之间创建一个关联,使得一个对象可以访问另一个对象的属性和方法,从而实现了继承
这里我在举个例子:
var lily = new Person("Lily") //创建一个lily实例对象
//实际上javaScript引擎执行了以下代码
var lily = {};
lily.__proto__ = Person.prototype;
Person.call(lily,"Lily")
我们来打印一下console.log(lily)
可以看出lily作为Person的实例对象,它的__proto__指向Person的原型对象(person.prototype)
根据这张图我们可以总结出以下几点:
1.每个函数的原型对象(person.prototype)都拥有constructor属性,指向该原型对象的构造函数(person)
2.使用构造函数(new Person())可以创建对象,创建的对象成为实例对象(lily)
3.实例对象通过将__proto__属性指向构造函数的原型对象(person.prototype),实现了该原型对象的继承
我们再来想想原型链又是什么东西呢。
现在我们知道,一个对象通过__proto__访问原型对象上的属性和方法,而该原型也同样可以通过__proto__来访问它的原型对象和方法,这样我们就在实例和原型之间构造了一条原型链,这里我将用红色的线将lily实例的原型链给标了出来,这样可以更直观的看出lily的原型链
那让我们再想想这javaScript是如何访问对象的方法和属性的
通过上面的理解,很容易想到javaScript是通过原型链来访问对象的方法和属性的,首先会优先在该对象上搜寻,如果找不到,还会通过原型链依次层层向上搜索该对象的原型对象,该对象的原型对象的原型对象等(套娃警告)最后javaScript中的所有对象都来自Object,Object.prototype.__proto__ === null null没有原型,并作为这个原型链中的最后一个环节,当javaScript遍历访问对象的整个原型链,如果最终依然找不到,此时会认为该对象的属性值为undefined。
但有一点需要注意当访问不存在的属性时,会遍历整个原型链,在原型链上查找属性十分耗费性能,因此当对象的原型链过长的时候,可以选择进行分解对象,让其原型链变短。
最后,让我们在好好理解这句话
构造函数本身的属性无法被对象实例共享,而原型对象上的属性和方法可以被所用对象实例所共享。
最后的最后,如果想知道自己对javaScript的原型和原型链真的理解没有那这有3个问题,可以检验你是否理解了
1.javaScript 的函数和对象是怎么样的关系?
2.__proto__和prototype都表示原型对象,他们有什么区别呢?
3.javaScript中对象的继承和原型链是什么关系?
可以在评论区上说出你的答案,让大家一起来讨论一下吧。