前言
看过不少深刻理解原型原型链系列,大体是明确不少,还是不够透彻!以下仅为集体总结和了解。
初见各名词
首先得理解这几个词:
函数,构造函数,函数原型(实例原型),实例,实例对象,对象原型,原型,prototype,__proto__,constructor
先看上面这个例子:
function Person() {}function Foo() {}const foo = new Foo();const person = new Person();
函数,构造函数:在下面的例子中构造函数就是Person函数原型(实例原型):前面会联合式子论述。(我的了解是最初始的函数,他的属性所有函数应用)
实例与实例对象:在下面的例子中,有构造函数Person、Foo,咱们用new操作符实例化了foo实例对象、person实例对象
原型对象与原型:前面会联合式子论述。
原型
任何一个构造函数都会有prototype属性。打印构造函数Foo.prototype,Person.prototype你会发现
console.log(Foo.prototype,Person.prototype);//{ constructor: f Foo(), __proto__: Object } { constructor: f Person(), __proto__: Object }
Foo.prototype,Person.prototype它们都指向各自函数的原型对象
a) 任何一个构造函数函数(Person,Foo),都领有一个prototype属性,它指向这个函数的原型对象
从打印进去的式子
{ constructor: f Foo(), __proto__: Object } { constructor: constructor: f Person(), __proto__: Object }
不难看出 Person.prototype和Foo.prototype都有constructor和__proto__属性。
而且Person.prototype.constructor和Foo.prototype.constructor都指向的是各自的构造函数自身。
能够通过式子大胆验证下:
console.log(Person.prototype.constructor === Person) // trueconsole.log(Foo.prototype.constructor === Foo) // true
b) 构造函数的prototype的constructor都是指向的构造函数的自身
那么Person.prototype.__proto__和Foo.prototype.__proto__指向什么呢?
console.log(Person.prototype.__proto__ === Object.prototype) // trueconsole.log(Foo.prototype.__proto__ === Object.prototype) // true
上式中的Person.prototype.__proto__和Foo.prototype.__proto__都指向Object.prototype
c) Person.prototype的原型指向Object.prototype
也就是说每个函数的原型都是Object的实例,那么Object.prototype的原型,new进去的foo,person的原型呢?
console.log(foo.__proto__);//{ constructor: f Foo(), __proto__: Object } console.log(person.__proto__);//{ constructor: f Person(), __proto__: Object }console.log(Object.prototype.__proto__);//null
不难看出
console.log(foo.__proto__===Foo.prototype);//trueconsole.log(person.__proto__===Person.prototype);//trueconsole.log(Object.prototype.__proto__===null);//true
d) foo,person的__proto(实例的原型) === Person.prototype;因而把Person.prototype叫做实例原型。
e) Person.prototype.__proto__(实例原型的原型) === Object.prototype;因而实例原型的原型指向的是Object.prototype。
f) Object.prototype.__proto__(Object.prototype的原型) === null;因而Object.prototype.__proto__ 的值为null,也就是Object.prototype没有原型。
再下面的 b 项中式子拿下来(b.构造函数的prototype的constructor都是指向的构造函数的自身)
console.log(Person.prototype.constructor === Person) // trueconsole.log(Foo.prototype.constructor === Foo) // true
那么Object.prototype.constructor是不是也是Object自身呢?
console.log(Object.prototype.constructor===Object)//true
g) Object.prototype.constructor === Object
由此讶羽大佬的关系图也就清晰了
原型链
由下面的剖析,能够看出原型链实际上就是运行const foo = new Foo()语句(创立实例函数时),产生了一个链条反馈,这个最顶端也就是原型链最顶端是Object.prototype.__proto__为null。
总结:从一个实例对象往上查找结构这个实例的相关联对象(原型对象),这个关联的对象(原型对象)通过__prototo__属性再往上找发明他的原型对象,以此类推,始终往上找,直到Object.prototype的原型对象为null完结的过程。
原型链是通过prototype的原型和__proto__的属性来实现原型链的查找。
原型与原型链只知其一;不知其二