咱们好多常常会被问道JavaScript原型和原型链的概念,还有关于继承,new操做符相关的概念。本文就专门整理了原型和原型链的概念,关于对象继承咱们后边进行介绍。本文包含对应的示例代码和脑图。若有奇异,欢迎指正!git
咱们先使用构造函数的方式声明一个对象:函数
function Person() {} let person = new Person() person.name = '小红' console.log(person.name) // 小红
在上面的代码中。Person是构造函数, person是经过new方式建立的实例对象。
如今开始进入一个环节post
prototype,constructor,__proto__是咱们常常见到的几个概念,可是他们之间的关系具体是什么样的呢,让咱们逐步开始了解。spa
每一个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型, prototype: 指向实例对象的原型对象
prototype
function Person() {} Person.prototype.name = '小红' let person = new Person() console.log(person.name) // 小红
Person这个函数有声明prototype属性,那么这个值指向的究竟是哪儿,是原型对象吗?code
其实prototype指向的是,调用当前构造函数建立实例对象的原型,也就是person的原型。对象
那么原型究竟是什么呢?其实原型能够理解为,一个JavaScript对象(null除外)在建立的时候会关联另一个对象,这个被关联的对象就是咱们说的原型对象,实例对象会在建立的时候,从原型对象继承一些属性或者方法。
继承
对应的关系图以下:ip
prototype讲解了构造函数和原型对象之间的关系,那么实例对象和原型对象之间的关系又是怎么样的呢?下面讲解。每一个JavaScript对象(null除外),都会有个__proto__的属性,这个属性指向的就是原型对象
function Person() {} let person = new Person() console.log(person.__proto__ === Person.prototype) // true // ES5 经过实例对象获取原型对象的方法 console.log(Object.getPrototypeOf(person) === Person.prototype) // true
由此咱们上面的管理系图谱能够补充为:
上面讲解了原型对象和构造函数,实例对象之间的关系,那么反过来获取原型对象和实例对象的构造函数是否是能获取到呢??constructor就能作到这一点。constructor: 指向该原型对象对应的构造函数
function Person() {} let person = new Person() // 原型对象的构造函数 console.log(Person.prototype.constructor === Person) // true // 实例对象的构造函数 console.log(person.constructor === Person) // true // 实例对象自己是否含有constructor属性 console.log(person.hasOwnProperty('constructor')) // false 注意: person.constructor 中其实是没有constructor属性的,这是从person的原型中获取到的constructor属性才有了 person.constructor === Person。经过
关系图能够补充为:
当咱们读取一个对象的属性是,若是实例对象中能找到,就会返回实例对象对应的value,若是没有找到,就会站到实例对象的原型对象中,查看有无此值,有则返回,没有的话,继续查找原型的原型对象上有无此值。一直会查到顶层为止。
function Person() {} Person.prototype.name = '小红' let person1 = new Person() let person2 = new Person() person2.name = '小明' console.log(person1.name) //小红 console.log(person2.name) //小明
那么原型的原型执行的是什么呢?
实际上,原型的原型也是一个实例对象,是经过Object的构造函数生成的,所以,原型的原型也能经过__proto__获取其对应的原型对象的属性。
function Person() {} Object.prototype.name = 'sunny' let person1 = new Person() let person2 = new Person() console.log(person1.name) //sunny console.log(person2.name) //sunny
对应的关系图以下:
console.log(Object.prototype.__proto__ === null) // true
Object.prototype的原型为null, null表明的意思是没有对象,为空。换句话的意思就是说,没有原型对象了,这也就是查找的顶层对象了。
整个的关系图咱们梳理为:
关系图中,红色的线其实就是咱们平时说的原型链
了
console.log(Person.__proto__ === Function.prototype) //true console.log(Object.__proto__ === Function.prototype) //true
console.log(Function.prototype.constructor === Function) // true console.log(Person.constructor === Function) //true console.log(Person.hasOwnProperty('constructor')) //false console.log(Object.constructor === Function) //true console.log(Object.hasOwnProperty('constructor')) //false
console.log(Function.prototype === Function.__proto__) // true console.log(Function.prototype === Function.prototype) //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
把这些所有总结完,以后咱们的关系图,就变成了下面这个样子:
JavaScript深刻之从原型到原型链