varHarrie / varharrie.github.io

:blue_book: Personal blog site based on github issues.
https://varharrie.github.io
MIT License
3.66k stars 544 forks source link

JavaScript原型链的简单总结 #21

Open varHarrie opened 6 years ago

varHarrie commented 6 years ago

JavaScript中万物皆是对象,且对象细分为普通对象函数对象

凡是通过new Function()创建的均为函数对象,如ObjectFunctionNumberBooleanStringArrayRegExp等等,其余都是普通对象

  1. 函数对象__proto__均指向Function.prototype,且为空函数function () {}
  2. 普通对象__proto__均指向该对象构造函数prototype
  3. Function.prototype.__proto__ === Object.prototype
  4. Object.prototype.__proto__ = null

对于普通对象:

function Person () {}
Person.prototype.say = function () {}

var p = new Person()
p.say()

Person相当于是构造函数,pPerson的实例,并且继承p的原型p.__proto__,即Person.prototype的所有属性。

当然,Person本身也是函数对象,这里我们考虑的是Person的实例p

p.constructor === Person // function Person () {}
p.constructor === Person.prototype.constructor // function Person () {}
p.__proto__ === Person.prototype // {say: function () {}}
p.__proto__ === p.constructor.prototype // {say: function () {}}
p.__proto__.__proto__ === Person.prototype.__proto__ === Object.prototype

对于函数对象:

var f = new Function()

f.__proto__ === Function.prototype // function () {}
f.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype

注意:

当我们重写原型对象,而不是修改原型对象时:

function Ghost () {}
Ghost.prototype = {} // 直接赋值一个对象

var g = new Ghost()

g.__proto__ === Ghost.prototype
g.__proto__ !== g.constructor.prototype
g.__proto__ === Object.prototype

这时,g.constructor指向的是Object,可以通过指定constructor避免这种情况:

function Ghost () {}
Ghost.prototype = {
  constructor: Ghost
}

var g = new Ghost()

g.__proto__ === Ghost.prototype === g.constructor.prototype

本文参考最详尽的 JS 原型与原型链终极详解,没有「可能是」进行总结,感谢原作者。