为什么摧毁了构造函数的prototype, 实例对象还能继承这个函数的属性?

FnaticE 2021-04-04 02:37:44

function Dog(name){
this.name=name;
}
let dogA=new Dog('Paul');

Dog.prototype.eat=true;
dogA.eat; //true,获得构造函数的eat属性

Dog.prototype=null; //将构造函数的原型改为null
dogA.eat; //true 。。。怎么实例对象还有eat?


照道理不是构造函数的prototype已经不存在了吗,完全变成了null,怎么dogA这个实例对象还能获得eat=true?
...全文
404 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
一品梅 2021-04-10
  • 打赏
  • 举报
回复
引用 2 楼 FnaticE 的回复:
[quote=引用 1 楼 丰云 的回复:]把Dog看成类,把dogA看成对象,就容易理解了
这个问题也困扰我几天了,现在有点想明白了,这压根不是继承的问题,而是指针指向的问题。 这个问题里Dog的原型对象,重新指向了null,相当于给Dog.prototype划分了一块新内存,存储着null。而原初的Dog.prototype所在的内存,值其实没有变,dogA.__proto__还是指向着那块老内存,eat: true就还存在。所以不论Dog.prototype被改成了什么,都不影响dogA.__proto__的指向了。但是如果新建的new Dog实例,可就会指向新的Dog.prototype所在的内存。 总结下来就是,已存在的实例不会因为构造函数的原型对象重新初始化而改变。用代码说明简洁一些:
let dogA.__proto__=Dog.prototype={eat: true};
Dog.prototype=null;
dogA.__proto__; //{eat: true}, 没变

let dogB=new Dog();
dogB.eat; //undefined
比较基础的知识,惭愧。 [/quote] 原型不是这样用的,是已经建立的类想扩展,你可以写个添加原型的属性。这样就和真正面向对象的扩展类相近的意思了。 添加属性和方法 有的时候我们想要在所有已经存在的对象添加新的属性或方法。 另外,有时候我们想要在对象的构造函数中添加属性或方法。 使用 prototype 属性就可以给对象的构造函数添加新的属性:
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}
 
Person.prototype.nationality = "English";
当然我们也可以使用 prototype 属性就可以给对象的构造函数添加新的方法:
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}
 
Person.prototype.name = function() {
  return this.firstName + " " + this.lastName;
};
QuickPai 2021-04-09
  • 打赏
  • 举报
回复
实例对象应实例化了,已经分配了内存,你给构造函数的原型对象赋值是不会改变实例对象的内容的。构造函数,实例对象,原型对象三者的关系搞明白。当函数经过new调用时,这个函数就成为了构造函数,否则只是普通函数。
FnaticE 2021-04-08
  • 打赏
  • 举报
回复
引用 1 楼 丰云 的回复:
把Dog看成类,把dogA看成对象,就容易理解了
这个问题也困扰我几天了,现在有点想明白了,这压根不是继承的问题,而是指针指向的问题。 这个问题里Dog的原型对象,重新指向了null,相当于给Dog.prototype划分了一块新内存,存储着null。而原初的Dog.prototype所在的内存,值其实没有变,dogA.__proto__还是指向着那块老内存,eat: true就还存在。所以不论Dog.prototype被改成了什么,都不影响dogA.__proto__的指向了。但是如果新建的new Dog实例,可就会指向新的Dog.prototype所在的内存。 总结下来就是,已存在的实例不会因为构造函数的原型对象重新初始化而改变。用代码说明简洁一些:
let dogA.__proto__=Dog.prototype={eat: true};
Dog.prototype=null;
dogA.__proto__; //{eat: true}, 没变

let dogB=new Dog();
dogB.eat; //undefined
比较基础的知识,惭愧。
丰云 2021-04-08
  • 打赏
  • 举报
回复
把Dog看成类,把dogA看成对象,就容易理解了

87,997

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧