原型和原型链
-
原型对象:原型对象(Person.prototype)是 构造函数(Person)的一个实例
- 因此只有构造函数才有原型对象prototype
-
每个对象都有
__proto__原型属性 【对象里面的内部属性__proto__】__proto__:原型也是一个对象- 注意:不是一个规范的属性,只是部分浏览器实现此属性
-
实例对象的原型
__proto__指向它所在的构造函数的原型对象prototype
原型链:
- 先从实例对象属性里找,找到了直接使用,如果实例属性找不到,然后去实例对象的
__proto__原型指向的它所在构造函数的原型对象里找,找到则使用,找不到才会报错- 这样一层一层搜索,就进行原型链
proto 、prototype、继承三者的关系
__proto__:
__proto__是每个 JavaScript 对象都具有的属性,它指向对象的原型。- 原型链是通过
__proto__属性来实现的,它允许对象继承其他对象的属性和方法。
prototype:
prototype是函数对象特有的属性,在创建函数时自动添加。prototype是一个包含函数对象的属性和方法的对象。- 当函数用作构造函数创建对象时,新对象的
__proto__属性会指向构造函数的prototype属性,从而实现继承。
总结:
- 1、所有对象都有__proto__属性来标识自己所继承的原型;
- 2、函数才有prototype属性;
- 3、创建函数时,JS会为这个函数自动添加prototype属性,值是一个有 constructor 属性的对象;
- 4、函数当作构造函数调用(通过new调用),JS会帮助创建构造函数的实例,实例通过设置自己的__proto__指向构造函数的prototype来实现继承;
__proto__的底层实现
__proto__ 属性的作用是允许对象直接访问其内部的 [[Prototype]] 属性,每个对象在创建时都会关联一个原型对象,可以通过 __proto__ 属性来获取它。
[[Prototype]] 是js对象内部的隐藏属性,指向该对象的原型
原型链应用场景
- 1、数据共享,对象属性和方法的共享
- 2、扩展原生对象的功能
- 2、继承的实现
原型链继承的缺点
- 共享属性的问题, 原型链继承通过共享原型对象上的属性和方法来实现继承,所有继承自同一个原型对象的实例将共享相同的属性。如果一个实例修改了原型对象上的属性,其他实例也会受到影响 【多实例之间会互相影响 => 引用类型属性互相影响 】