1 原型对象重写后的constructor属性
function Animal(){}
function Cat(){}
let cat1 = new Cat();
Cat.prototype = new Animal();
目标很明确, 就是想要 cat1
继承Cat
继承Animal
.
将构造函数Cat
的原型对象重写后, 相当于此时的Cat.prototype
成为了Animal
的实例对象, 那么它现在的constructor
属性是什么呢?
1.1
console.log(Cat.prototype)
控制台打印:
可见, 当原型对象重写后, 原先具有的constructor
属性就不存在了.
但是我在这里还是试着打印一下
1.2
console.log(Cat.prototype.constructor)
控制台打印:
我们仍然获得了相应的数值, 且为构造函数Animal
, 这里就是原型链的作用.
当构造函数Animal
实例化了对象Cat.prototype
的同时, 从1.1控制台打印信息可得, 该实列对象具备了一个__proto__
的属性.
实际上, js中的每一个对象都有__proto__
属性, 该属性会指向其构造函数的原型对象, 当我们需要访问对象的某个属性时, 就会从对象本身开始顺着__proto__
这条链往上寻找一直到Object.prototype.__proto__ (也就是null)
为止.
代码中的Cat.prototype.__proto__
指向的是Animal.prototype
, 所以当Cat.prototype
中未找到constructor
属性时, 会继续往上从Animal.prototype
中寻找. 此时,也就获得了Animal.prototype.constructor
, 该属性指向构造函数Animal
.
通常, 我们会将constructor
重置回原来的构造函数, 已确保后续的一些使用
function Animal(){}
function Cat(){}
let cat1 = new Cat();
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat; //动态添加属性,重置回原构造函数Cat
此时, Cat.prototype
构造函数再次回到了Cat
, 而Cat.prototype.__proto__
指向却变成了Animal.prototype
, 实现了我的需求.
结论: 重写原型对象, 其constructor
属性也随之消失. 通常我们会将constructor
’属性重制, 而对象与对象之间的继承关系实际上就是.__proto__
和.prototype
间的关系.
2 原型对象重写在代码中的位置问题
function Animal(){}
function Cat(){}
let cat1 = new Cat();
Cat.prototype = new Animal(); //在实例cat1之后
Cat.prototype.constructor = Cat;
Cat.prototype.age = 99;
console.log(Object.prototype.__proto__ === null); //true
console.log(Animal.prototype.__proto__=== Object.prototype); //true
console.log(Cat.prototype.__proto__ === Animal.prototype); //true
console.log(cat1.__proto__ === Cat.prototype); //false
console.log(cat1.age); //undefined
理想的原型链应该是
cat1.__proto__
-->Cat.prototype
Cat.prototype.__proto__
-->Animal.prototype
Animal.prototype.__proto__
-->Object.prototype
Object.prototype.__proto
-->Null
但是, 实际结果是cat1.__proto__
并未指向Cat.prototype
, cat1
也没有继承属性age
.
造成这一问题的原因是原型对象重写的位置在新建实例对象cat1
之后引起的,
当cat1
创建后, 这时的cat1.__proto__
指向最初的Cat.prototype
所在的地址.
而当Cat.prototype
被重写后, 此时又开辟了一片新的地址内存储它, 所以实际上此时cat1.__proto__
并未指向Cat.prototype
, 也就无法继承其相应属性.
解决这一问题只要将其位置调换或重新指向即可:
function Animal(){}
function Cat(){}
Cat.prototype = new Animal(); //在实例cat1之前
let cat1 = new Cat();
//或者添加 cat1.__proto__ = Cat.prototype;
Cat.prototype.constructor = Cat;
Cat.prototype.age = 99;
console.log(Object.prototype.__proto__ === null); //true
console.log(Animal.prototype.__proto__=== Object.prototype); //true
console.log(Cat.prototype.__proto__ === Animal.prototype); //true
console.log(cat1.__proto__ === Cat.prototype); //true
console.log(cat1.age); //99
OVER, 小白要继续自学了~~~