proto

在JavaScript里面,一切皆为对象,而对象(除了null)都有proto,这个属性会指向该对象的原型,即作为实例对象和实例原型的之间的链接桥梁。
proto属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]]。
所以直接使用它进行原型对象的操作是很不友好的,它的目的只是为了访问到原型对象里的属性。

1
2
3

let obj = {a:'1'};
console.log(obj.__proto__);

prototype

prototype是函数特有属性,因为实现面向对象的编程方式,需要有类似继承等属性,而原型对象即可解决此类问题,且保存javascript的灵活多变的方式。
函数上使用prototype,可proto变成合法的操作,而不单单只是一个访问器,可对其添加修改删除等,而在函数上proto与prototype是相等的,因为它们都指向同一个内存地址,但在实际上他们是不一样的,因为除了函数,其他对象都没有prototype属性。

1
2
3
4
5
6
function Person() {

}

var person = new Person();
console.log(person.__proto__ === Person.prototype); //true;

##构造函数、实例对象、原型对象

1
2
3
4
5
6
7
function Person(){}

Person.prototype.getName = function(){
return 'proto';
}

let per = new Person();

Person这个函数的prototype属性指向了一个对象,即:Person.prototype也是一个对象。这个对象正是调用该构造函数而创建的实例的原型。

既构造函数与原型对象、实例对象都是需要new一个实例对象时才能正确使用。

1
2
3
4
1.调用的构造函数:  Person
2.使用什么调用: new关键字
3.得到了什么: 实例化对象per
4.实例化对象和原型是什么关系: per的原型就是 Person.prototype

而原型就是实例对象都共享原型上的属性,而原型对象包含proto对象,指向上层原型对象,当实例对象访问某个属性时,先查询对象本身所函数的属性是否存在该属性,否则访问原型对象上的属性,而当当前原型对象不含有,则通过proto对象访问上层原型对象属性,直到访问到该属性或proto指向的顶层对象Object后停止访问。