原型和原型链

301 阅读2分钟

什么是原型

每一个引用对象都有一个隐式原型__proto__,这个属性是一个对象。隐式原型的__proto__指向他的构造函数prototype显式原型。当你试图得到对象的某个属性,如果本身没有这个属性,那么会去它的隐式原型__proto__即构造函数的prototype中寻找。

function Person (name) {
    this.name = name
}
let p = new Person('xl')
p.__proto__ === Person.prototype // true,在new操作符中实际也有这一步,让新建的空对象原型指向构造函数的Prototype,这样就可以访问到原型链上的属性
console.log(p) 
console.log(Person.prototype)

image.png

image.png 可以看到构造函数的原型对象有一个constructor属性指向构造函数,所以又有了一个闭环, Person.prototype.constructor === Person // true

image.png

原型链

原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。 所有对象的的原型最后都会指向Object.prototype,Object的原型又指向null,这样是为了避免死循环

image.png

  • 每个对象__proto__指向它的构造函数的Prototype
p.__proto__ === Person.prototype
  • 构造函数原型的__proto__又指向Object的prototype
Person.prototype.__proto__ === Object.prototype
  • 所有的构造器都是函数对象,所以Object的__proto__又指向了函数的Prototype
Object.__proto__ === Function.prototype
  • 函数的原型对象也是对象,所以又指向了Object的原型
Function.prototype.__proto__ === Object.prototype
  • Object原型的__proto__最终指向了null,结束的原型链的过程
Object.prototype.__proto__ === null

面试题

let F = function () { }
Object.prototype.a = function () { console.log('a'); }
Function.prototype.b = function () { console.log('b'); }
let func = new F()

func.a() // a
func.b() // TypeError: func.b is not a function
F.a() // a
F.b() // b

因为F是一个构造函数,在他的原型链上会找到FunctionObject的原型对象,所以会正常输出a和b。而func是构造函数F的实例对象,一切对象最终都继承自Object,所以在func的原型链上只有Object原型对象上的a方法,没有继承到Function构造函数上的b方法

image.png

image.png

image.png

结语

写的不好,有些错误或者没有表达清楚的地方还请各位大佬指正,感谢家人 感恩🙏