js原型继承问题,请教了(腾讯的一道面试题) 本帖最后由 wangzhichao666 于 2011-11-08 16:10:01 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 window.onload = function() { function Dog(name){ this.name = name; } Dog.prototype = { constructor : Dog, wow: function() { alert('wow'); }, yelp: function() { return this.wow(); } } function CrazyDog(name){ this.name = name; } CrazyDog.prototype = new Dog(); CrazyDog.prototype.madYelp = function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } //test xiaoXian var xiaoXian = new Dog("xiaoXian"); var xiaoXianBtn = document.getElementById('xiaoXianBtn'); xiaoXianBtn.onclick = function() { xiaoXian.yelp(); }; //test xiaoMang var xiaoMang = new CrazyDog("xiaoMang"); var xiaoMangBtn = document.getElementById('xiaoMangBtn'); xiaoMangBtn.onclick = function() { xiaoMang.madYelp(); };}; 这里MadDog重复定义了,本来是MadDog.__proto__绑定了Dog(F.prototype) var MadDog = Object.beget(Dog); MadDog = { madYelp: function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } };=====================================可以把madYelp改成对象方法,优雅点的话应该从Dog对象extend出来一个madYelp方法来var MadDog = Object.beget(Dog); MadDog['madYelp']= function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } //alert(MadDog.__proto__.wow);//实际上wow方法在这里找到,可在ff/chrome 下去掉注释看看这一行 其实楼主封装好的那个函数还是挻有用的,其他的其实是参考你的代码。var MadDog = Object.beget(Dog); MadDog.madYelp = function(){ _self = this setInterval(function(){ return _self.wow(); },2000); }; var MadDog = Object.beget(Dog); MadDog = { madYelp: function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); }var MadDog = 11111; MadDog = 2222222;... 其实我的实现是不同的 MadDog.madYelp = function(){ _self = this setInterval(function(){ return _self.wow(); },2000); };是给Dog的实例MadDog添加了一个madYelp 成员变量。。我的实现是把CrazyDog看为Dog的一个分类,而它的madYelp是CrazyDog的原型方法xiaoMang是CrazyDog的实例 如果是我,我就实现一个Extend方法。比如jquery的$.extend,Ext的Ext.Extend,这个东西太常用了。 如果给Dog,extend一个方法出来,那它以后的实例不是都有这个方法了么?可能题目需求的是MadDog是Dog的一个子类,并不给Dog加一个madYelp方法? 不 , 8 楼的 , 它直接错了 . var MadDog = Object.beget(Dog); MadDog = { madYelp: function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } };认真看 , 第二行的时候 , 他把 MadDog = {};以前里面所有的东西都覆盖了 , 所以找不到 wow 了 . 我说的的Extend是对象copy,不是Dog对象本身添加方法。var MadDogCfg = extend(Dog,{'madYelp':function(){}});var MadDog = Object.beget(MadDogCfg); 。。我没说他代码没错啊。。MadDog = {}之前的原型方法都被覆盖了 而且我觉得楼主的方法,xiaoMang这些实例都没办法追溯父类。。因为Dog根本不是一个构造函数。。它只不过是通过Object.beget这个方法将Dog的成员变量赋值给了F的原型,然后new F()出来而已。。我觉得和原型继承没什么关系,只不过是完成的需求的功能而已 其实他本是想 var MadDog = Object.beget(Dog); MadDog.madYelp = function(){ _self = this setInterval(function(){ return _self.wow(); },2000); };但是他错误的MadDog = { madYelp: function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); }};导致MadDog原型被覆盖掉了,也就是没有了继承,所以导致出错。 呵呵,我也觉得这题切入点有点偏,按我说要考prototype直接上来Object.prototype.a = 1;var t = function(){};alert(t.a)var nt = new t();alert(nt.a)说说t.a是循着怎样一条原型链找到的a属性的。同理说说nt.a 应该是之前的MadDog 被后来的覆盖掉了,以下的例子可以清晰地看到这一点<script type="text/javascript"> var a={ getName:function(){ alert('小方'); } }; a.getName(); a={ getNick:function(){ alert('芳芳'); } }; a.getName();</script>第一次可以调用getName方法,而第二次却不能了 看到大家的回复,我很高兴,因为有答案了,所以问题不能编辑,我把面试题目放在下面:这是腾讯2007年web前端面试的第一题。小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:帮助function Dog() { this.wow = function() { alert(’Wow’); } this.yelp = function() { this.wow(); }}小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实现(提示关键字: 继承,原型,setInterval)。 这个是淘宝的WEB题,不是腾讯的··· if (typeof Object.beget !== 'function') { Object.beget = function(o) { var F = function() {}; F.prototype = o; return new F(); };}window.onload = function() { var Dog = { wow: function() { alert('wow'); }, yelp: function() { return this.wow(); } }; var MadDog = { getParent: Object.beget(Dog),//继承Dog madYelp: function() { _self = this; setInterval(function() { return _self.getParent.wow(); }, 2000); } }; //test xiaoXian var xiaoXian = Object.beget(Dog); var xiaoXianBtn = document.getElementById('xiaoXianBtn'); xiaoXianBtn.onclick = function() { xiaoXian.yelp(); }; //test xiaoMang var xiaoMang = Object.beget(MadDog); var xiaoMangBtn = document.getElementById('xiaoMangBtn'); xiaoMangBtn.onclick = function() { xiaoMang.madYelp(); };}; 看到17楼才明白楼主的意思。下面是我的实现,很直接,很易懂。<script type="text/javascript">function Dog() { this.wow = function() { alert('Wow'); } this.yelp = function() { this.wow(); }}function MadDog() { this.wow = function() { alert('Wow'); setTimeout(this.wow(), 500); }}MadDog.prototype = new Dog();//让MadDog从Dog派生var xiaoXian = new Dog();var xiaoMang = new MadDog();//安装事件处理函数window.onload = function(){ var xiaoXianBtn = document.getElementById("xiaoXianBtn"); var xiaoMangBtn = document.getElementById("xiaoMangBtn"); 调用的都是同一个yelp函数,但分发到不同的wow函数,这不正是面向对象的虚函数的多态行为吗? xiaoXianBtn.onclick = function(){xiaoXian.yelp();}; xiaoMangBtn.onclick = function(){xiaoMang.yelp();};}</script><input type="button" id="xiaoXianBtn" value="小贤的正常叫声"/><input type="button" id="xiaoMangBtn" value="小芒的疯叫声"/>经测试在IE和FireFox表现正常。点一下小贤,叫一下【弹出消息框】。点一下小芒,就不停地叫【弹出消息框】。在IE下只能使用任务管理器关闭,在火狐只需关闭标签就可以了。这一点火狐要好一些。我没有使用setInterval,setTimeout就足够用了。 var MadDog = Object.beget(Dog); MadDog = { madYelp: function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } };这样写是对MadDog重新赋值,当然会出错了。。 if (typeof Object.beget !== 'function') { Object.beget = function(o) { var F = function() {}; F.prototype = o; return new F(); }; } window.onload = function() { var Dog = { wow: function() { alert('wow'); }, yelp: function() { return this.wow(); } }; var MadDog = Object.beget(Dog); MadDog.madYelp = function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } //test xiaoXian var xiaoXian = Object.beget(Dog); var xiaoXianBtn = document.getElementById('xiaoXianBtn'); xiaoXianBtn.onclick = function() { xiaoXian.yelp(); }; //test xiaoMang var xiaoMang = Object.beget(MadDog); var xiaoMangBtn = document.getElementById('xiaoMangBtn'); xiaoMangBtn.onclick = function() { xiaoMang.madYelp(); }; }; <html><script>if (typeof Object.beget !== 'function') { Object.beget = function(o) { var F = function() {}; F.prototype = o; return new F(); };}window.onload = function() { var Dog = { wow: function() { alert('wow'); }, yelp: function() { return this.wow(); } }; var MadDog = Object.beget(Dog); MadDog.madYelp = function() { var _self = this; setInterval(function() { return _self.wow(); }, 2000); } //test xiaoXian var xiaoXian = Object.beget(Dog); var xiaoXianBtn = document.getElementById('xiaoXianBtn'); xiaoXianBtn.onclick = function() { xiaoXian.yelp(); }; //test xiaoMang var xiaoMang = Object.beget(MadDog); var xiaoMangBtn = document.getElementById('xiaoMangBtn'); xiaoMangBtn.onclick = function() { xiaoMang.madYelp(); };}; </script><head></head> <body> <input type="button" id="xiaoXianBtn" value="小贤的正常叫声"/><input type="button" id="xiaoMangBtn" value="小芒的疯叫声"/> </body></html> var MadDog = Object.beget(Dog);Dog 是局部变量,这条应该就无法通过了吧 求jseclipse插件的新地址 截取字符串的问题。进来小看一下 大家来研究一下CSDN论坛的筛选得分贴和人的JAVASCRIPT脚本 新手问个语法问题 同志们帮忙看看CSDN上的这个网页效果是怎么实现的? 内网用户搭建的网站,怎么才能被外网访问? 如何得到一个页面所有数量文本框input的合计值 初学者:求能够兼容ie和firefox的读取xml的代码 怎么在让用户在浏览器中输入网址以后就谈出一个对话框? easyui 如何将定义的控件 拉到datagrid 筛选列中 救急!救急! js里调用VBArray的返回值问题???? js来判断是否值已改变,但没有办法实现
function Dog(name){
this.name = name;
}
Dog.prototype = {
constructor : Dog,
wow: function() {
alert('wow');
},
yelp: function() {
return this.wow();
}
}
function CrazyDog(name){
this.name = name;
}
CrazyDog.prototype = new Dog();
CrazyDog.prototype.madYelp = function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
} //test xiaoXian
var xiaoXian = new Dog("xiaoXian");
var xiaoXianBtn = document.getElementById('xiaoXianBtn');
xiaoXianBtn.onclick = function() {
xiaoXian.yelp();
};
//test xiaoMang
var xiaoMang = new CrazyDog("xiaoMang");
var xiaoMangBtn = document.getElementById('xiaoMangBtn');
xiaoMangBtn.onclick = function() {
xiaoMang.madYelp();
};
};
var MadDog = Object.beget(Dog);
MadDog = {
madYelp: function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
};
=====================================
可以把madYelp改成对象方法,优雅点的话应该从Dog对象extend出来一个madYelp方法来
var MadDog = Object.beget(Dog);
MadDog['madYelp']= function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
//alert(MadDog.__proto__.wow);//实际上wow方法在这里找到,可在ff/chrome 下去掉注释看看这一行
其实楼主封装好的那个函数还是挻有用的,其他的其实是参考你的代码。
var MadDog = Object.beget(Dog); MadDog.madYelp = function(){
_self = this
setInterval(function(){
return _self.wow();
},2000);
};
MadDog = {
madYelp: function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
var MadDog = 11111;
MadDog = 2222222;...
MadDog.madYelp = function(){
_self = this
setInterval(function(){
return _self.wow();
},2000);
};
是给Dog的实例MadDog添加了一个madYelp 成员变量。。我的实现是把CrazyDog看为Dog的一个分类,而它的madYelp是CrazyDog的原型方法xiaoMang是CrazyDog的实例
var MadDog = Object.beget(Dog);
MadDog = {
madYelp: function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
};
认真看 , 第二行的时候 , 他把 MadDog = {};
以前里面所有的东西都覆盖了 , 所以找不到 wow 了 .
var MadDog = Object.beget(MadDogCfg);
MadDog = {}
之前的原型方法都被覆盖了
MadDog.madYelp = function(){
_self = this
setInterval(function(){
return _self.wow();
},2000);
};但是他错误的MadDog = {
madYelp: function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
};导致MadDog原型被覆盖掉了,也就是没有了继承,所以导致出错。
直接上来
Object.prototype.a = 1;
var t = function(){};
alert(t.a)
var nt = new t();
alert(nt.a)
说说t.a是循着怎样一条原型链找到的a属性的。
同理说说nt.a
var a={
getName:function(){
alert('小方');
}
};
a.getName();
a={
getNick:function(){
alert('芳芳');
}
};
a.getName();
</script>第一次可以调用getName方法,而第二次却不能了
这是腾讯2007年web前端面试的第一题。
小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:
帮助
function Dog() {
this.wow = function() {
alert(’Wow’);
}
this.yelp = function() {
this.wow();
}
}
小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实现(提示关键字: 继承,原型,setInterval)。
Object.beget = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
}
window.onload = function() {
var Dog = {
wow: function() {
alert('wow');
},
yelp: function() {
return this.wow();
}
};
var MadDog = {
getParent: Object.beget(Dog),//继承Dog
madYelp: function() {
_self = this;
setInterval(function() {
return _self.getParent.wow();
}, 2000);
}
};
//test xiaoXian
var xiaoXian = Object.beget(Dog);
var xiaoXianBtn = document.getElementById('xiaoXianBtn');
xiaoXianBtn.onclick = function() {
xiaoXian.yelp();
};
//test xiaoMang
var xiaoMang = Object.beget(MadDog);
var xiaoMangBtn = document.getElementById('xiaoMangBtn');
xiaoMangBtn.onclick = function() {
xiaoMang.madYelp();
};
};
function Dog() {
this.wow = function() {
alert('Wow');
}
this.yelp = function() {
this.wow();
}
}function MadDog() {
this.wow = function() {
alert('Wow');
setTimeout(this.wow(), 500);
}
}
MadDog.prototype = new Dog();//让MadDog从Dog派生var xiaoXian = new Dog();
var xiaoMang = new MadDog();//安装事件处理函数
window.onload = function(){
var xiaoXianBtn = document.getElementById("xiaoXianBtn");
var xiaoMangBtn = document.getElementById("xiaoMangBtn");
调用的都是同一个yelp函数,但分发到不同的wow函数,这不正是面向对象的虚函数的多态行为吗?
xiaoXianBtn.onclick = function(){xiaoXian.yelp();};
xiaoMangBtn.onclick = function(){xiaoMang.yelp();};
}
</script><input type="button" id="xiaoXianBtn" value="小贤的正常叫声"/>
<input type="button" id="xiaoMangBtn" value="小芒的疯叫声"/>经测试在IE和FireFox表现正常。点一下小贤,叫一下【弹出消息框】。点一下小芒,就不停地叫【弹出消息框】。在IE下只能使用任务管理器关闭,在火狐只需关闭标签就可以了。这一点火狐要好一些。
我没有使用setInterval,setTimeout就足够用了。
MadDog = {
madYelp: function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
};这样写是对MadDog重新赋值,当然会出错了。。 if (typeof Object.beget !== 'function') {
Object.beget = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
}
window.onload = function() {
var Dog = {
wow: function() {
alert('wow');
},
yelp: function() {
return this.wow();
}
};
var MadDog = Object.beget(Dog);
MadDog.madYelp = function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
//test xiaoXian
var xiaoXian = Object.beget(Dog);
var xiaoXianBtn = document.getElementById('xiaoXianBtn');
xiaoXianBtn.onclick = function() {
xiaoXian.yelp();
};
//test xiaoMang
var xiaoMang = Object.beget(MadDog);
var xiaoMangBtn = document.getElementById('xiaoMangBtn');
xiaoMangBtn.onclick = function() {
xiaoMang.madYelp();
};
};
<script>if (typeof Object.beget !== 'function') {
Object.beget = function(o) {
var F = function() {};
F.prototype = o;
return new F();
};
}
window.onload = function() {
var Dog = {
wow: function() {
alert('wow');
},
yelp: function() {
return this.wow();
}
}; var MadDog = Object.beget(Dog);
MadDog.madYelp = function() {
var _self = this;
setInterval(function() {
return _self.wow();
}, 2000);
}
//test xiaoXian
var xiaoXian = Object.beget(Dog);
var xiaoXianBtn = document.getElementById('xiaoXianBtn');
xiaoXianBtn.onclick = function() {
xiaoXian.yelp();
};
//test xiaoMang
var xiaoMang = Object.beget(MadDog);
var xiaoMangBtn = document.getElementById('xiaoMangBtn');
xiaoMangBtn.onclick = function() {
xiaoMang.madYelp();
};
};
</script>
<head></head>
<body>
<input type="button" id="xiaoXianBtn" value="小贤的正常叫声"/>
<input type="button" id="xiaoMangBtn" value="小芒的疯叫声"/>
</body>
</html>