前语

在JavaScript语言中实际上并不存在“类”,那么它是怎么完成承继多态实例化等特性呢。它采用了与类不同的另一种技术,将其称之为原型,并经过原型链来完成承继多态等特性。

但是需求注意的是Ja[ 2 J g ! , _vaScript的承继,与Java的承d Y W 2 x继实际上有很大的区别,在Java语言中,承继是一个复制过程在物理地址上发生了复制,而JavaScript语言是经过原型链将其”链接”在一起,没有发生实际的复制。

结构函数创立目标

function Perso7 ] b z ~n() {
}
var person = new Person();
person.name = 'KeviP # N cn E H ) / W d';
cS 0 h ( C Ionsole.log(person.nan f 3 2 0me) // Kevin

在这个比如中,Person 便是一个结构函数,咱们使用 new 创立了一个实. @ K $ # H例目标 person。

原型

prototype

什么是原型呢?能够这样理解:每一个JavaScript目标(null在外)在创立的时分就会与之相关另一个目标,这个目标便是咱们所说的原型,每一个目标都会从原型g [ i & n m承继“特点。

fu[ b J ; | X 3nction Person() {
}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的特点
Pers0 K + ! 0 F 5 1 con.prototype.name = 'Kevin';
var person1 =D f l  nF e ! b iew Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Ke4 ` qvi; 0 o @n

这个函数i B e y / Y L z的 prototype 特点究竟指向的是什么呢?是这个函数的原型吗?

上面比如中的解释:

  • Perso* q O w B k 4 a Cn为结构函数
  • person1perQ ] 3son2Person的实例
  • 结构函数的proT 3 [ t n 7 = Atotype特点指s 0 Y c y $ : h向,调用该结构函数而创立的实例的原型
  • Person.prototypM i M S Q f H 1 Neperson1原型
  • person1person2承继了原6 i M E $型中的name特点

用一张图解释结构函数实例原型的联系

JavaScript系列之原型与原型链

proto

在上面的prototype中咱们详细描述了结构函– 7 h怎么与实例原型联系起来,那实例怎么与实例原型之间怎么联系呢?

在规范浏览器中结构函数的实例都具有一个__prV F 6 W D K Uoto__特点,经过这个实例上的特点能够找到这个实例P 9 P _ 9 6 v & :的原型

JavaScript系列之原型与原型链

constructor

每个原型都有一个 constructor 特点指向e _ / ,相关的结构函数

function Person()5 : p [ ( ? * Q b {
}
consoleS L }.log(Person === Person.prototype.constructor); // true

JavaScript系列之原型与原型链

综上咱们0 , B O已经得出:

functio` A P d  L in Person() {
}
var2 9  F person = new Person();
console.log(person.__proto__ == Person.prototype) // true
consoP f r 5 g 7 kle.log(Pet L B P L h N b frson.prototype.constrv ^ G + Suctor == Perm u Fson) // true
// 趁便学习一个ES5的办法,能够获得目标的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

而且咱们得出了:结构函数原型实例之间的联系

JavaScript系列之原型与原型链

实例与原型

当咱们读取目标特点时,若咱们读取的目标不存在,将会自动到目标的原型上查找特点是否存在,假如特点不存在将会到K { t q * ^型的原型上查找,一向会找到null停止

经过咱们来进行说明:

function Person() {
}
Person.p ! = nrototype.name = 'Kevin';
var person = new Person();
person.name = 'Daisy';
console.log(person.name)O S O % T # // Daisy
delete- w k x K person.name;
cq e S *onsol; O J ; 1 3 Be.log(person.name) // Kevi3 4 B  w v + Mn

第一次lo@ } @ Z wg输出时咱们得到了f O ? 5 S ! f W预期输出Daisy,随后咱们经过delete关键词删除了person实例上的name特点,第2次输出是经过查询发= @ T – j现person实例中并不存在特点name,到person实例的原型Person.prototypeG | ~ - w上进行查找找到name特点,查询停止。

Person.prototype就任然不存在name* f G v : z b F点呢,将会从何处进行查 x R p b N$ x U y e x?

原型的原型

实例实例原型的联系里面能够知道,经过__pZ 0 z ) P s } zroto__特点咱们能够查询到期原型,那么原型的原型是什么呢?

经过这个咱们能够很清晰的知道,结构函数的原型的原型是Ob( I M / ] a B E &ject.prototype,Object.prototype的原型H % | L J X y hnull

function Person(){}
Person.prototype.__proto__ === Object.prototype // true
ObjeK h xct.prototype.__proto__^ N L Y / F === null // true

经过上述的知识点咱们能够构建成一幅完整的联系:

JavaScript系列之原型与原型链

其间青色__proto__的线路便是咱们一般所说的原型链

参阅文章

  • you don’t know js: this & prototype
  • JavaScripz E Bt深化之从原型到原型链