绕来绕去的prototype,__proto__,constructor

今天发现自己又搞不明白prototypeprotoconstructor这些属性直接的区别了。。故此总结一下O_0·

function Person() {
    this.category = 'human'
}

function Female() {
    this.sex = 'female'
}

Female.prototype = new Person()
var xia = new Female()
var chinese = new Person()

以上例子中,有两个类,Person类,和Female类,Female类的prototype属性为Person类的一个实例,而xia和chinese则分别是Female类和Person类的实例

prototype

表示对象的原型。

xia.prototype // undefined
Female.prototype // Person {category: 'human'}
Person.prototype // Object {contructor: person(), __proto__: Object}

_proto_

xia.__proto__ // Person {category: 'human'}
Female.__proto__ // function () {}
Person.__proto__ // function () {}

出现这种情况的主要原因是以下两点:
1. 所有构造器/函数的都指向Function.prototype,它是一个空函数(Empty function)
2. 所有对象的proto都指向其构造器的prototype,即 chinese.constructor.prototype === chinese.__proto__

由上可知,xia.__proto__ === xia.constructor.prototype,而xia.constructor这里为啥等于Person函数嘞?看下面的constructor的讲解


constructor

xia.constructor // function Person() {this.category = 'human'}

constructor始终指向创建当前对象的构造(初始化)函数。
任何一个prototype对象都有一个constructor属性,指向它的构造函数。
每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性。即xia.constructor === Female.prototype.constructor
每个函数都有一个默认的属性prototype,而这个prototype的constructor默认指向这个函数

正常情况下,xia.constructor即是Female.prototype,应该指向其构造函数,也就是Female(),但是由于之前将Female.prototype指向了Person类的实例,即Person {category: 'human'},故
xia.constructor === Female.prototype === chinese.constructor === function Person () {}
这样看来,是很不好的,导致继承链的紊乱(xia明明是用构造函数Female生成的),因此我们必须手动纠正,将Female.prototype对象的constructor值改为Female.prototype.constructor = Female
这是很重要的一点,编程时务必要遵守。下文都遵循这一点,即如果替换了prototype对象,那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。

你可能感兴趣的:(绕来绕去的prototype,__proto__,constructor)