原型
概念
- 原型就是一个概念
- 每个函数都有一个
prototype
属性,该属性指向当前函数的显示原型对象
,指向Object对象 - 每个实例对象都有一个
__proto__
属性,该属性指向当前实例对象的隐示原型对象
,指向Object对象 - 构造函数的显示对象 === 当前构造函数的实例对象的隐示原型对象
把一个构造函数可以看成一个类,原型是所有类都有的一个属性,原型的作用就是给这个类的每一个对象都添加一个统一的方法。
在es5时候我们通常使用大写开始的函数作为构造函数。
// 创建一个原型对象
function Person() { }
//1、 每个函数都有一个Prototype
console.log(Person.prototype); // {constructor: ƒ} 空对象 ==>原型对象Object对象(显示对象)、
console.log(Person.prototype.constructor); //指向原型对象本身
// 声明当前的构造函数
console.log(Person.prototype.constructor); // 指向函数本身
// 创建一个实例
let person = new Person()
// 2、 每个实例对象都有一个__proto__属性,这个属性指向当前对象的原型对象(隐式对象)
// 3、构造函数的显示对象===实例的隐式对象
console.log(Person.prototype === person.__proto__); // true
显示原型vs隐式原型
每个函数都有一个
prototype
为显示原型
。而每个实例
都有__proto__
,称为隐示原型
。对象的隐示对象的值为构造函数显示对象的值。Person.prototype === person.__proto__
。
- 函数的prototype属性:在定义函数时自动添加,默认为
空Object对象
- 对象的
__proto__
属性:创建时自动添加,默认为构造函数的prototype
属性值 - 我们能直接操作
显示对象
而不能直接操作隐示对象
问:为什么
prototype
创建出来的叫显示原型,而__proto__
叫隐示原型?而不能直接操作隐示原型呢?
// 创建一个构造函数
function Person(){}
//问 为什么不是使用__proto__ 而是使用prototype呢
Person.prototype.eat = function(){
return '吃饭'
}
let person = new Person()
person.__proto__.eat = function(){
return '吃饭'
}
对象的属性中,不加的属性/方法是内置对象意味着我们可以直接去调用,而加开头的我们是不可以直接使用的。所以__proto__
是不可以直接使用的,所以才叫做隐示
。
什么时候用到原型
但需要操作公共方法的时候可以直接放在原型对象上,供所有的实例对象使用,可以节省内存开销。
原型链
概念