javascript关于原型对象重写后的问题

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, 小白要继续自学了~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值