这两个属性跟js的原型链强相关,什么是原型链,就是当获取一个属性时,先在实例中查找,找不到就沿着__proto__一直往上面(该实例的原型、该实例的原型的原型、该实例的原型的原型的原型、....)找,找到就返回,找不到直到找到null
,原型链主要能够实现属性的共享和独立控制。
先放一张网上经典完整版原型链大图
![](https://img.haomeiwen.com/i12172259/98932cccd2b19445.png)
prototype
只有函数才有此属性
![](https://img.haomeiwen.com/i12172259/2aa0e4abb45a80eb.png)
__proto__
对象有此属性,因为在js中万物借对象,所以不管是函数、数字、字符串等都会有__proto__
属性,只有undefined、null
没有__proto__
属性。
![](https://img.haomeiwen.com/i12172259/fd95b5985cfa1b5c.png)
1.通过字面意思我们新建一个对象
const obj = {name:"小米"}
obj是一个对象,所以它拥有__proto__
属性,它的__proto__
属性指向Object.prototype
,为什么指向Object.prototype
,后面再解释,而Object.prototype
这个对象上拥有对象的共同属性及方法,比如:toString、hasOwnProperty、isPrototypeOf
等,这就是所以obj对象能够使用上面的这些方法。从而实现属性、方法的共享,而name
属性是obj对象自定义的,这就是属性的独立控制。当读取一个对象的属性时。首先会去实例中找,找不到就是对象的原型上找,这样一直递归的往上找,实在找不到就返回null
,因为最顶层的指向就是null
。
![](https://img.haomeiwen.com/i12172259/0ad6dd388840902f.png)
2.通过构造函数创建实例
function Animal(age, name) {
this.age = age;
this.name = name;
}
const monkey = new Animal(12, "monkey");
其中monkey
的__proto__
属性指向Animal
的prototype
![](https://img.haomeiwen.com/i12172259/588453ec74822857.png)
因为
monkey
是构造函数Animal
构建的,所以monkey
的__proto__
属性指向Animal
的prototype
。而Animal.prototype
是个对象,Animal.prototype.__proto__
指向Object.prototype
![](https://img.haomeiwen.com/i12172259/2ba468cd9e53fe89.png)
__proto__
就是一个类似于一个链子的作用,网上说它也是指针,他就是讲原型和实例进行一个链接的作用,类似于继承的作用。而prototype
就是原型属性,在上面可以定义方法和属性,而该原型下的所有实例都能够使用这些方法和属性。![](https://img.haomeiwen.com/i12172259/15fddae9d5bce6f8.png)
在js中除开
undefined、null
没有__proto__
属性,都有__proto__
属性,那么Function,Object,以及定义function的__proto__指向谁呢
。Object.__proto__、Function.__proto__、定义function的__proto__
指向Function.prototype
,因为Object、Function、定义function
都是函数构建出来的,所有他们的原型就是Function.prototype
![](https://img.haomeiwen.com/i12172259/9136149006f91228.png)
Function.prototype
的__proto__
指向Object.prototype
。所有就有来刚开始的那一张图![](https://img.haomeiwen.com/i12172259/bcb2d56fef0bd8d1.png)
到最后都会指向
Object.prototype
,Object.prototype.__proto__指向null
网友评论