苏秦陶侃博客

js之原型链

字数统计: 680阅读时长: 2 min
2018/12/19 Share

js之原型链

js中万物皆对象吗

由一个简单的对象实例说起:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Person (name, age) {
this.name = name
this.age = age
}

Person.prototype.getName = function () {
console.log(this.name)
}

const person = new Person('Tom', 12)
person.getName() // Tom
console.log(person.__proto__) // {getName: ƒ, constructor: ƒ}
console.log(person.constructor)
/**
* ƒ Person (name, age) {
this.name = name
this.age = age
}
*/

先不解释代码,介绍几个js中非常重要的概念:

prototype

  1. prototype:函数的一个属性,叫原型对象。js中函数所特有的属性,如果是这个函数是构造函数,那么它的实例对象上也能访问到prototype上的属性,其实就是一种变相的“继承”。

    《JavaScript权威指南》

    Every JavaScript object has a second JavaScript object (or null ,
    but this is rare) associated with it. This second object is known as a prototype, and the first object inherits properties from the prototype.

       每一个js对象都有另一个与之相关联的对象,另一个对象就是原型对象,此对象继承原型对象上的属性和方法。

    翻译出来就是每个JS对象一定对应一个原型对象,并从原型对象继承属性和方法。

    __proto__

  2. __proto__:可称为隐式原型,所有js对象(除去null)都有的一个属性,一个对象的隐式原型指向构造该对象的构造函数的原型。

由于__proto__是个内部属性,不建议外部直接使用,现在一般建议使用Object.getPrototypeof方法来查看原型对象。

  1. constructor:所有原型对象都有的一个属性,指向当前对象的(自己的)构造函数。

原型链文字总结

  js中所有对象都是由构造函数生成的,而js中函数拥有属性prototype,由它实例化得到的是js对象,js对象(除去null)又都拥有__proto__属性,并且这个属性是指向构造函数的prototype,从而实例对象可以访问到构造函数原型对象上的属性或方法。

  这也就是js的原型链。

原型链结合开始代码的图示总结

image-20190114233907816
  由于Function的原型也是对象那么它的构造函数是Object,所以Function原型的隐式原型(__proto)指向的是Object的原型(prototype);Function自己也是对象,而它的构造函数就是他自己,所以他的隐式原型(__proto)指向他自己的原型。

  而Object.prototype是没有原型的,隐式原型(__proto)指向null,
Object又是Function的实例,所以他的隐式原型(__proto)指向Function的原型。

这就是js中著名的先有鸡还是先有蛋的问题。

参考文献

  1. http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html
  2. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
  3. https://github.com/creeperyang/blog/issues/9
CATALOG
  1. 1. js之原型链
    1. 1.1. prototype
    2. 1.2. __proto__
    3. 1.3. 原型链文字总结
    4. 1.4. 原型链结合开始代码的图示总结