__proto__、Prototype、constructor
__proto__
__proto__属性指向原型对象,也可以理解为父类对象,它是所有对象(包括函数)都有的。
prototype
函数的原型对象,给其它对象提供共享属性,函数所独有的。它跟原型链没有关系。它的作用是:构造函数new对象的时候,告诉构造函数新创建的对象的原型是谁。
原型链
当你在访问一个对象属性的时候,如果该对象内部不存在这个属性,那么就回去它的__proto__属性所指向的对象(父类对象)上查找,如果父类对象依旧不存在这个属性,那么就回去其父类的__proto__属性所指向的父类的父类上去查找。以此类推,直到找到 null。而这个查找的过程,也就构成了我们常说的原型链。
constructor
constructor属性是一个对象指向该对象的构造函数。对象所独有属性。每一个对象都有其对应的构造函数,本身或者继承而来。
通常obj.constructor === obj.__proto__.constructor
原型继承
让子类的原型对象指向父类的实例,当子类的实例找不到对应的属性时,他会沿着原型链往上找。
__proto__ 与 prototype 与 constructor
function Father(){ this.a =1; } // Father是函数对象 let child = new Father() // child是普通对象
- Father._ proto_ === Function.prototype // 函数对象的原型指向函数的原型对象
- Function._ proto_ === Function.prototype // Function的原型指向函数原型对象
- Object._ proto_ === Function.prototype //Object的原型指向函数原型对象
- Function.prototype._ proto_ === Object.prototype //Function的原型对象的原型指向Object的原型对象
上述四个看着很蒙?那么看下面三个
- child._ proto_ === Father.prototype //child 的原型指向构造函数Father的原型对象
- Father.prototype._ proto_ === Object.prototype //Father 的原型对象的原型指向Object的原型对象
- Object.prototype._ proto_ === null //Object的原型对象的原型指向null【原型链顶层】
child是通过Father使用new构造出来的实例对象,所以child的原型指向Father的prototype
其实child.constructor是在__proto__原型中找到的constructor
child.constructor === Father // true
child.__proto__.constructor === child.constructor // true
所以其实是这么一个结构:
子类实例对象:(
属性方法
__proto__ ==> 父类(
父类属性方法
constructor: function 子类(){}
__proto__ ==> 父类的父类(
父类的父类属性方法
constructor: function 父类(){}
__proto__。。。一直套娃,最后套到Object,然后是null
)
)
)
下面看一段原型代码
function Foo(name) { this.name = name; } Foo.prototype.myName = function(){ return this.name; } function Bar(name, label){ Foo.call(this,name); this.label = label; } // 创建新的Bar.prototype对象并关联到Foo.prototype Bar.prototype = Object.create(Foo.prototype); // Notice!现在没有Foo.prototype.constructor了,因为prototype被整个替换成了{}
Bar.prototype.myLabel = function(){ return this.label; } var a = new Bar('a', 'obj a'); a.myName(); //'a' a.myLabel(); //'obj a'
解决办法
可以使用ES6提供的新方法,这样就不会破坏结构了
Object.setPrototypeOf(Bar.prototype, Foo.prototype)
引用:https://blog.csdn.net/m0_38073011/article/details/108500396