原型
什么是原型:每个函数身上都会有一个prototype
属性,这个属性是一个对象,这个对象就是通过构造函数创建出来的实例对象的原型。
__proto__
与 prototype
首先要明确一点:__proto__
是在实例对象上的,而prototype
是函数的特有属性,同时函数也拥有__proto__
属性。下文会说。
而将实例与其原型连接起来的条件就是,实例对象的__proto__
指向构造函数的prototype
。
function Person(name) {
this.name = name
}
const person = new Person('paul')
console.log(person.__proto__ === Person.prototype) // true
注意点:只要创建一个函数,那么这个函数就会有prototype
属性,默认情况下,所有原型对象都会获得一个constructor
属性,而这个属性也会指回构造函数。
console.log(Person.prototype.constructor == Person) // true
那么__proto__
,prototype
,constructor
之间的关系是什么呢?通过下图可以很直观的表达三者的关系。
原型链
原型链是什么呢,原型链就是当访问对象的实例或者方法时,但是实例对象本身并不具有,那么就会沿着原型一直查找,所形成的查找链就是原型链,原型链的顶端是Object
的原型,最终结果为null
。
通常原型和原型链很容易绕晕,但是记住这几点就会很好的理解。
- 函数的
prototype.constructor
指向函数本身。 - 只有函数身上才有
prototype
属性,同时函数也拥有__proto__
属性,因为函数也是一个对象,在定义函数时,会通过new Function()
来定义。Function
的__proto__
与prototype
相等。 - 实例的
__proto__
属性指向构造函数的prototype
属性。 - 函数的
prototype
也是一个对象,因此他也有__proto__
属性。 - 原型链的顶端为Object,
Object.prototype.__proto__ = null
,查找到这里没有就会返回undifined
看过下面的例子会更好的理解。
function Person(name) {
this.name = name
}
const person = new Person('paul')
console.log(person.__proto__ === Person.prototype) // true
console.log(person.__proto__.__proto__.__proto__); // null 一直查找到顶端为null
console.log(Person.__proto__ == Function.prototype) // true
console.log(Person.prototype.__proto__ == Object.prototype) ; // true Person.prototype的原型为Object.prototype
console.log(Person.prototype.constructor == Person) // true 构造函数的 prototype.constructor 指向本身
原型与原型链
理解了下面这些会帮助更好的了解原型和原型链。
console.log(Object)
console.log(Object.__proto__) // ƒ () { [native code] }
console.log(Object.__proto__.prototype) // nudefined 对象没有prototype
console.log(Object.prototype.__proto__) // null Object的原型为null
console.log(Object.prototype.constructor === Object); // true
console.log(Object.prototype) // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} Object.prototype为对象
console.log(Function)
console.log(Function.__proto__) // ƒ () { [native code] }
console.log(Function.__proto__.prototype) //对象没有prototype
console.log(Function.prototype.__proto__) // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
console.log(Function.prototype) // ƒ () { [native code] }
console.log(Function.prototype.__proto__ === Object.prototype) // true Function的上一级为Object
console.log(Function.prototype === Function.__proto__) // true
原型链可以帮助实例对象更好的访问到自身没有的属性和方法,在实例上重新定义原型链上的属性或方法后,原型链上的属性和方法将被覆盖。使用同一个构造函数构造多个对象,那么这些对象上的属性将会共享,这也是原型链的一个缺点。
以上为我对原型和原型链的理解,如果不妥之处,欢迎大家指正,共同进步!!!