继承与prototype下的方法顺序有何影响

soldierluo 2010-02-27 09:16:15
代码如下

<script>
function person(){
this.name = "BillGates";
}
person.prototype.say = function(){alert(this.name);}

function employee(){
this.salary = 5000;
}
employee.prototype.show = function(){alert(this.salary);}
employee.prototype = new person();

var bill = new employee();
alert(bill.show);
</script>

如果是上面的代码,bill无法访问show函数,但是如果将employee.prototype.show = function(){alert(this.salary);}放到employee.prototype = new person();的后面的话就可以访问show方法了,请问这是为什么

在我看来employee.prototype = new person();这句是根本不会影响employee.prototype下的show方法的
...全文
211 20 打赏 收藏 举报
写回复
20 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
soldierluo 2010-03-01
  • 打赏
  • 举报
回复
囧 很是受打击呀!!!

new person() 对象覆盖了 employee.prototype对象,这就是原因~~~
foolbirdflyfirst 2010-03-01
  • 打赏
  • 举报
回复
引用 15 楼 soldierluo 的回复:
引用 13 楼 foolbirdflyfirst 的回复:
//employee.prototype.__proto__ ---> Object.prototype
employee.prototype.show = function(){alert(this.salary);}
//employee.prototype.__proto__ ---> person.prototype
//person.prototype.__proto  ---> Object.prototype
employee.prototype = new person();

都直接把__proto__指向改了,当然就找不到show方法了。
你还是没看懂那张图咧。
不好意思,辜负了,理解正在进行时
employee.prototype.show = function(){alert(this.salary);} 时
//employee.prototype.__proto__ ---> Object.prototype
employee.prototype.show = function(){alert(this.salary);}
是将show方法是增加到Object.prototype对象上

employee.prototype = new person(); 时
//employee.prototype.__proto__ ---> person.prototype 由于__proto__指向的改变,所以上面增加到Object.prototype上的show方法就无法访问到了
//person.prototype.__proto__ ---> Object.prototype

这样就解释通了

龙腾虎跃
我开始的理解是__proto__作为prototype的一个属性,即使被改变了也只是改变了__proto__的值,而原本加在prototype上的属性不应该受影响。主要是没理解到[class].prototype.__proto__是指向Object.prototype这一点

dear soldierluo
是将show方法是增加到Object.prototype对象上
千万不要这么理解啊,不要误入大坑。那个箭头是指本对象找不到就应该到下个对象去找
你这个问题其实是自己把自己绕进去了,很简单的赋值问题。
你那个employee.prototype对象是给覆盖了,就这么简单啊,上面很多坛友都说了。
你的问题如同以下


//1
employee.prototype = {
show:function(){}
}
//2
employee.prototype = new person();

不就是两个赋值语句么?而show是赋值语句右边对象里的一个属性而已,所以employee.prototype被覆盖后,去哪找show属性呢?
2当然覆盖1了
就相当于
var a = '1';
a = 2;
a当然等于2了
葬月礼 2010-03-01
  • 打赏
  • 举报
回复
我认为#12 #14楼说得很简单,复杂的问题简单化。 说通了就是对象的属性被重新赋值了,更新了原先对象的属性导致原先的属性丢失
soldierluo 2010-03-01
  • 打赏
  • 举报
回复
引用 14 楼 s_title 的回复:
    看到龙腾虎跃的回答,才知道你就是上次那个问继承的。 呵呵。

现在这个问题实在是简单不过。可能是你大意了, 很简单的例子:

比如说: a.b=c;//a对象的b属性等于c对象,实际上a对象的b属性就是c ;

    a.b.d=12;//在a对象的b属性上添加d属性, 实际上就是在c对象上添加了d属性;

    a.b=e;// 将a对象的b属性重新设置为e对象?

  现在你问a对象的b属性上还有d这个属性吗?  你说有没有咯。

  跟你问的那个问题一样的原型。

谢谢,主要是被那个创建对象三部曲绕晕了,还有没有理解__proto__
s_title 2010-03-01
  • 打赏
  • 举报
回复
简单的问题,复杂化。 只能说楼主你加油。
soldierluo 2010-03-01
  • 打赏
  • 举报
回复
引用 13 楼 foolbirdflyfirst 的回复:
//employee.prototype.__proto__ ---> Object.prototype
employee.prototype.show = function(){alert(this.salary);}
//employee.prototype.__proto__ ---> person.prototype
//person.prototype.__proto  ---> Object.prototype
employee.prototype = new person();

都直接把__proto__指向改了,当然就找不到show方法了。
你还是没看懂那张图咧。

不好意思,辜负了,理解正在进行时
employee.prototype.show = function(){alert(this.salary);} 时
//employee.prototype.__proto__ ---> Object.prototype
employee.prototype.show = function(){alert(this.salary);}
是将show方法是增加到Object.prototype对象上

employee.prototype = new person(); 时
//employee.prototype.__proto__ ---> person.prototype 由于__proto__指向的改变,所以上面增加到Object.prototype上的show方法就无法访问到了
//person.prototype.__proto__ ---> Object.prototype

这样就解释通了

龙腾虎跃
我开始的理解是__proto__作为prototype的一个属性,即使被改变了也只是改变了__proto__的值,而原本加在prototype上的属性不应该受影响。主要是没理解到[class].prototype.__proto__是指向Object.prototype这一点
s_title 2010-03-01
  • 打赏
  • 举报
回复
看到龙腾虎跃的回答,才知道你就是上次那个问继承的。 呵呵。

现在这个问题实在是简单不过。可能是你大意了, 很简单的例子:

比如说: a.b=c;//a对象的b属性等于c对象,实际上a对象的b属性就是c ;

a.b.d=12;//在a对象的b属性上添加d属性, 实际上就是在c对象上添加了d属性;

a.b=e;// 将a对象的b属性重新设置为e对象?

现在你问a对象的b属性上还有d这个属性吗? 你说有没有咯。

跟你问的那个问题一样的原型。
foolbirdflyfirst 2010-03-01
  • 打赏
  • 举报
回复
//employee.prototype.__proto__ ---> Object.prototype
employee.prototype.show = function(){alert(this.salary);}
//employee.prototype.__proto__ ---> person.prototype
//person.prototype.__proto ---> Object.prototype
employee.prototype = new person();

都直接把__proto__指向改了,当然就找不到show方法了。
你还是没看懂那张图咧。
cloudgamer 2010-03-01
  • 打赏
  • 举报
回复
相当于
var a = {b:1}
a = {c:1}
alert(a.b);这里当然是undefined了
cloudgamer 2010-03-01
  • 打赏
  • 举报
回复
很简单
employee.prototype.show = function(){alert(this.salary);}
employee.prototype = new person();
后面那个等于重写了employee.prototype当然前面的show没有了啊
licip 2010-02-28
  • 打赏
  • 举报
回复
1楼的说法很对,让我学习了。谢谢!
soldierluo 2010-02-28
  • 打赏
  • 举报
回复
我上面的理解好像也不对,还是用上面两位高手的说法吧
soldierluo 2010-02-28
  • 打赏
  • 举报
回复
我知道原因了
当employee.prototype.show = function(){alert(this.salary);}时,show方法是增加到employee.prototype对象中,此时employee.prototype.__proto__是指向employee.prototype也就是自身;
而employee.prototype = new person();时,employee.prototype.__proto__就改变了,变成了employee.prototype.__proto__ = person.prototype;employee.prototype的指向改变了,不再指向employee.prototype,所以原本增加到employee.prototype上的方法或属性都会丢失掉

所以最重要的还是对象的__proto__,__proo__属性的指向决定了对象下的属性和方法,也就是所谓的原型链吧!!!
我觉得这样理解应该没错了
soldierluo 2010-02-28
  • 打赏
  • 举报
回复
那也就是说,在使用继承的时候,son.prototype = new father();必须紧跟在son对象的后面啰,否则就会丢失掉在其之前做的对son.prototype的改变了
wcwtitxu 2010-02-28
  • 打赏
  • 举报
回复
简化下 用 a 代替 employee.prototype

a.show = function() { ... }; // 给 a 加一个新的方法 show()
a = new person(); // 整个 a 被你换成一个新的对象; a.show 就没啦

// --------------------------

a = new person(); // a 被赋为一个新的对象
a.show = function() { ... }; // 再给 a 加一个新的方法 show(), 当然 a.show 就可以访问了
soldierluo 2010-02-27
  • 打赏
  • 举报
回复
温故而知新
你这样说我觉得很难理解,可以解释下内部的操作吗
s_liangchao1s 2010-02-27
  • 打赏
  • 举报
回复

// 模拟employee的原型prototype
var pro = {}
function employee() {};
// 开始时employee原型指向的是pro对象
employee.prototype = pro;
// 原型的show方法
pro.show = function() {
alert('pro对象的show属性');
}
// 模拟个person对象
function Person() {
this.name = 'Person对象';
}
Person.prototype.say = function() {
}
// 现在employee指向的是new Person对象
employee.prototype = new Person();

var em = new employee();
try {
/**
em查找show属性的顺序. 首先找自身构造没有
就顺着__proto__链找自己的prototype原型.
但此时__proto__ = new Person了.
*/
em.show();
} catch (e) {
alert(em.name)
}

soldierluo 2010-02-27
  • 打赏
  • 举报
回复
何况employee的prototype对象是本身就存在的
soldierluo 2010-02-27
  • 打赏
  • 举报
回复
楼上,我的理解是
employee.prototype = new person();
等于下面
employee.prototype.__proto__ = person.prototype;
person.call(employee.prototype);
所以,employee.prototype = new person();根本不该影响之前对employee.prototype的修改,谢谢
s_liangchao1s 2010-02-27
  • 打赏
  • 举报
回复

因为原型prototype本身就是个对象实例
employee.prototype.show = function(){alert(this.salary);}
可以理解为
employee.prototype = {};
employee.prototype.show = function(){alert(this.salary);}
也就是.show是属于{}对象的属性.

employee.prototype = new person();
这句话new Person也是个对象 就把prototype这个对象给覆盖了 当然他上面的属性也找不到了.

而你第二种情况是先设置new person对象. 然后show属性再加的new person对象上. 所以可以访问到


发帖
JavaScript

8.7w+

社区成员

Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
帖子事件
创建了帖子
2010-02-27 09:16
社区公告
暂无公告