prototype
在ES6之前,不存在Class属性,面向对象是通过构造函数来实现的,这个方法有一个弊端,每次创建方法时,都会为实例单独开辟一个内存空间,比较浪费内存。因此我们需要原型对象prototype属性来调用共同的(不变)方法。这样所有实例对象就可以共享这些方法了。
```javascript
function Star(uname,age){
this.uname=uname;
this.age=age;
}
Star.prototype.sing=function(){
console.log(‘唱歌‘)
}
var boa=new Star(‘BoA‘,18);
var tooko=new Star(‘tooko‘,16);
boa.sing();
tooko.sing();
//可以调用相同的sing方法
```
总结: 原型:每一个构造函数都有一个 prototype 属性,指向另一个对象。这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。原型的作用:共享方法。
__proto__
工作原理:实例对象原型:实例对象有一个属性 ```__proto__ ```指向构造函数的 prototype 原型对象。
实例对象原型```__proto__ ```和构造函数的prototype是等价的。举例上面的```boa.__proto__===Star.prototype```;
方法的查找规则:首先先看对象身上是否有方法,如果有就执行这个对象上的方法,如果么没有这个方法,因为有```__proto__ ``` 的存在,就去构造函数原型对象prototype身上去查找方法。
constructor 属性
实例对象原型( ```__proto__ ```)和构造函数原型对象(prototype)里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。
一般情况下,对象的方法都在构造函数的原型对象中设置。如果有多个对象的方法,我们可以给原型对象采取对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。此时,我们可以在修改后的原型对象中,__添加一个 constructor 指向原来的构造函数。__
```
Star.prototype = {
constructor: Star,
sing: function () {
console.log(唱歌);
},
movie: function () {
console.log(电影);
}
}
```
三者的关系:
prototype:每一个构造函数都有一个prototype属性,指向的是该构造函数的原型对象。
__proto__:每一个实例对象都有一个__proto__属性,指向构造函数的原型对象。
constructor:实例对象原型__proto__和构造函数prototype原型对象里面都有一个属性 constructor 属性 ,都指向了构造函数。
1.构造函数的prototype属性指向了构造函数原型对象。
2.实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象。
3.构造函数的原型对象的constructor属性指向了构造函数,实例对象的原型的constructor属性也指向了构造函数。
原型链
当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。如果还没有就查找原型对象的原型(Object的原型对象)。依此类推一直找到 Object 为止(null),按照原型链的方式去查找。

内置对象的拓展方法可以用“."的形式追加,而不能采用对象{}的形式进行覆盖

构造函数实例和原型对象关系总结
原文:https://www.cnblogs.com/tooko/p/13221185.html