1.对象的构造函数
在原型对象中有一个属性 constructor
可以直接指向构造函数。
function Person() {
}
console.log(Person.prototype.constructor)//Person构造函数本身
因为构造函数创建的实例化对象本身没有constructor
属性,但是因为连接到了Person函数的原型对象,就可以访问到constructor
属性。
console.log(new Person().constructor)//Person构造函数本身
因为通过对象的constructor
属性可以查询到它的构造函数
原型链的结构
- 自定义函数,以及Object、String、Number等内置函数,都是由Function函数自身创建的。
- 每一个构造函数都有一个原型对象,构造函数通过
prototype
属性指向原型对象,原型对象通过constructor
指向构造函数。 - 由构造函数创造的实例对象,继承自构造函数的原型对象,通过对象的
__proto__
属性可以直接访问原型对象 - 构造函数的原型对象,继承自Object的原型对象,而Object的原型对象的
__proto__
属性为空。 - 实例化对象的
constructor
属性可以直接访问原型对象继承的构造函数。
原型链示意图如下
脚下留心
在进行原型操作时,对象.constructor.prototype
访问的是该对象当前继承的原型对象的构造函数的原型对象,并不一定是,实例构造函数的原型对象。
实例
function Person() {}
function Fun() {}
Person.prototype = new Fun();
var p1 = new Person();
p1.constructor === Fun;
p1.constructor.prototype === Fun.prototype;
p1.__proto__ === Person.prototype
判断1
p1.constructor === Fun;//true
通过构造函数创建的实例对象,他可以直接通过constructor
直接访问构造函数的原型对象,
因为创建之前Person.prototype = new Fun();
,所以
p1.constructor === Person.prototype.constructor;
p1.constructor === (new Fun()).constructor;
等价于实例对象 Fun的constructor
属性==Fun
判断2
p1.constructor.prototype === Fun.prototype;//true
上次判断已经指向了构造函数Fun.
判断3
p1.__proto__ === Person.prototype//true
实例对象的__prtoto__
属性可以直接访问原型对象。
多学一招
instanceof
运算符可以用来检测一个原型链中是否含有某个构造函数的prototype所代表的对象,有返回true ,没有返回false;
function Person() {};
function Fun() {};
var p1 = new Person();
console.log(p1 instanceof Person); //true
console.log(p1 instanceof Fun); //false
如果在创建之后更改了Person构造函数的prototype
属性为其他对象,那么在使用instanceof
检测时,之前创建的对象就不在Person的原型链中了。
function Person() {
this.aa = 1
}
function Fun() {
this.aa = 2
}
var p1 = new Person()
Person.prototype = new Fun();
var p2 = new Person();
console.log(p1 instanceof Person); //false
console.log(p2 instanceof Person); //true
总结
通过修改原型对象继承的只是原型对象的方法,而构造函数的属性不会变化。
如果想要把属性也继承过来,改变this指向。
如果 想要改变原来的原型对象。
p1.__proto__.__proto__ = Person.prototype