乐趣区

关于javascript:原型与原型链一知半解

前言

看过不少深刻理解原型原型链系列,大体是明确不少,还是不够透彻!以下仅为集体总结和了解。

初见各名词

首先得理解这几个词:
函数,构造函数,函数原型(实例原型),实例,实例对象,对象原型,原型,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) // true
console.log(Foo.prototype.constructor === Foo) // true

b)构造函数的 prototype 的 constructor 都是指向的构造函数的自身

那么 Person.prototype.__proto__和 Foo.prototype.__proto__指向什么呢?

console.log(Person.prototype.__proto__ === Object.prototype) // true
console.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);//true
console.log(person.__proto__===Person.prototype);//true
console.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) // true
console.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__的属性来实现原型链的查找。

原型与原型链只知其一; 不知其二

退出移动版