原型与原型链是js的难理解的点之一,但是只要认真去理解,也会有所收获💜💜💜
在介绍原型与原型链之前,我们先搞懂下面问题
- proto:隐式原型
- prototype:显式原型
- 对象都有隐式原型__proto__。
- 函数有显示原型prototype。
- 对象的__proto__指向其构造函数的prototype。
下面先理解三个概念:
每一个对象都有一个__proto__属性,他指向该对象的原型
function Person(){}
var person1 = new Person()
console.log(person1.__proto__ === Person.prototype) // true

每一个函数都有一个 prototype 属性,该属性指向函数的原型对象
function Person(){}
Person.prototype.name = "protoName"
var person1 = new Person()
console.log(person1.name) // protoName
解释:

每个原型都有一个constructor属性,指向该关联的构造函数。
从constructor属性来讲,只有prototype对象才有这个属性,而其它对象的constructor属性都是通过__proto__对象从prototype继承而来
function Person(){}
var person1 = new Person()
console.log(Person.prototype.constructor === Person) // true
console.log(Person.prototype.constructor === person1.constructor) // true
解释:

函数在创建时,JS会为该函数创建一个对应的prototype对象,而这个prototype对象的constructor属性又指向该函数,即Foo.prototype.constructor === Foo。
原型对象上的所有属性和方法,都能被对应的构造函数创建的实例对象共享*(这就是 JavaScript继承机制的基本设计),也就是说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。
每一个构造函数都有一个prototype(原型)属性,这个属性就是使用构造函数创建出来的实例对象的原型对象。
原型链用于基于现有对象构建新类型的对象。它类似于基于类的语言中的继承。
对象实例上的原型可通过Object.getPrototypeOf(object)或proto属性获得,而构造函数上的原型可通过Object.prototype 获得。
原型链特点:
- 读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。
- 如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding
就近原则
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.address = function(){
console.log("地址");
}
var xiaoming= new Person("小明");
xiaoming.address();
构造函数Person通过prototype指向Person的原型对象prototype
Person原型对象prototype通过自身具有的construtor属性指回构造函数Star
Person创建了对象实例xiaoming,xiaoming通过自身具有的__proto__属性指向其原型对象
一级级向上,在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链
以后有更深更好懂的解释,我会慢慢补充💜💜