学习javascript遇到的一个问题。

wyman25 2011-11-19 12:43:08
我在学习js继承特性中,在尝试call与prototype比较的时候,遇到了这个问题:

<script type="text/javascript">
var father=function(){
this.name="father";
}
var child=function(){
child.prototype=new father();
}
var son=new child();
alert(child.prototype.name);
alert(son.name);
</script>

IE8和chrome第一个弹出框是"father",但第二个弹出框却是undefined。百思不得其解:既然第一个弹出框是"father",也就是说child.prototype的确是new father()这个对象,但为什么son并没有获得father.name属性呢?然后我将“child.prototype=new father();”这句放在child函数外面,变成:

<script type="text/javascript">
var father=function(){
this.name="father";
}
var child=function(){
//child.prototype=new father();//放到child外面执行
}
child.prototype=new father();
var son=new child();
alert(child.prototype.name);
alert(son.name);
</script>

结果两个弹出框都是"father"。为什么这语句在child里面执行,son就不能继承到father(即使son的构造函数child的prototype已经是new father())?为什么放在外面就可以? 是不是域的问题?求解答!!!
我在js版的积分不多,请不要嫌弃
...全文
248 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
峭沙 2011-11-23
  • 打赏
  • 举报
回复
其实变量的传递并不是js独有的特性,一般的编程语言都一样,基本类型是值传递,对象是引用传递
liangws 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 zeewendotnet 的回复:]

就一点基础只是不是很牢固导致一个问题几乎解决不了,再次多谢liangws,不过能不能告诉我还有哪些更深入的特性要去弄懂的?我google了很久,最深入的都还是prototype的原理。
算了,结贴。
[/Quote]
js特性太多了。。你可以看看周爱民的 javascript语言精髓与编程实践,里面说了很多js特别的地方
wyman25 2011-11-22
  • 打赏
  • 举报
回复
就一点基础只是不是很牢固导致一个问题几乎解决不了,再次多谢liangws,不过能不能告诉我还有哪些更深入的特性要去弄懂的?我google了很久,最深入的都还是prototype的原理。
算了,结贴。
liangws 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zeewendotnet 的回复:]

昨天又想了一个晚上,又要多谢lingws,我想我想通了:
第一次new的时候还是像我之前说的那样创建了空对象,空对象的__proto__指向child.prototype,然后执行“child.prototype=new father();”。这时如lingws所说,prototype是引用传递,son.__proto__和child.prototype已经指向不同的对象了,前者是child原……
[/Quote]
楼主真是好学啊~其实自己想通的问题是最好的!
峭沙 2011-11-22
  • 打赏
  • 举报
回复
变量的传递
峭沙 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zeewendotnet 的回复:]

昨天又想了一个晚上,又要多谢lingws,我想我想通了:
第一次new的时候还是像我之前说的那样创建了空对象,空对象的__proto__指向child.prototype,然后执行“child.prototype=new father();”。这时如lingws所说,prototype是引用传递,son.__proto__和child.prototype已经指向不同的对象了,前者是child原……
[/Quote]呵呵,恭喜你答对了。这问题的关键就是new的实现方式以及变量的值传递问题
wyman25 2011-11-22
  • 打赏
  • 举报
回复
昨天又想了一个晚上,又要多谢lingws,我想我想通了:
第一次new的时候还是像我之前说的那样创建了空对象,空对象的__proto__指向child.prototype,然后执行“child.prototype=new father();”。这时如lingws所说,prototype是引用传递,son.__proto__和child.prototype已经指向不同的对象了,前者是child原来的prototype对象,后者才是new father()。所以第一次new时候,son是没有name属性的。我后来在"var son=new child();"后面加了一句做验证:alert(son.__proto__==child.prototype),输出是false(chrome和ff,IE8好像不允许访问__proto__,值是undefind,输出false)。
对于lingws六楼的例子:child.prototype.name = "123"; //改变副本,不改变引用,child.prototype执行的仍然是当初默认的chil.prototype,并且和son.__proto__的指向是相同的,只是加了个name属性。
wyman25 2011-11-20
  • 打赏
  • 举报
回复
嗯..我其实还没有停止想这个问题,我再思考一下你得话。顺便问一句:lingws是怎样学到js这些东西的?看什么书,或者是什么资料?我在google上搜很久,最深入的都是prototype的一些原理,更深入的东西已经找不到了,不知道是那些方面的资料?
liangws 2011-11-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zeewendotnet 的回复:]

经过一天的思考google加分析liangws的说话,我想我已经想通了:
首先,当浏览器执行到“var son=new child();”的时候,遇到了new的时候,就开辟了内存创建了对象(可以认为是一个空对象,这也是为什么new后面的构造函数叫“构造函数”的原因),创建了这个空对象的时候同时又将child函数的prototype赋值给了这个空对象(实际上是:这个空对象的__proto__指针……
[/Quote]
其实差不多。但是关键点没理解到
然后执行完这些后,再执行接下来的构造函数里面的代码,也就是“child.prototype=new father();”但很可惜,son的__prototype__已经指向了默认的child.prototype了(而且child.prototype并不是father对象,所以没有name属性),这时再设置child.prototype为new father()已经错失了赋予那个空对象任何father的属性的时机了

其实他已经设置对了。但是prototype是对象,你只改变了对象的引用,影响到的只是后面new出来的实例
我6楼的例子,改变的是prototype的副本,所以直接就影响到当前的实例了,再放出例子,楼主参考下
其实关键点是对象是引用传递

var father=function(){
this.name="father";
}
var child=function(){
// child.prototype=new father();
child.prototype.name = "123"; //改变副本,不改变引用,
}
var son=new child();
alert(child.prototype.name);
alert(son.name);




wyman25 2011-11-20
  • 打赏
  • 举报
回复
经过一天的思考google加分析liangws的说话,我想我已经想通了:
首先,当浏览器执行到“var son=new child();”的时候,遇到了new的时候,就开辟了内存创建了对象(可以认为是一个空对象,这也是为什么new后面的构造函数叫“构造函数”的原因),创建了这个空对象的时候同时又将child函数的prototype赋值给了这个空对象(实际上是:这个空对象的__proto__指针指向了child.prototype,需要注意的是此时的child.prototype仍然是默认的prototype,因为还没有执行到构造函数里面那句“child.prototype=new father();”)。然后执行完这些后,再执行接下来的构造函数里面的代码,也就是“child.prototype=new father();”但很可惜,son的__prototype__已经指向了默认的child.prototype了(而且child.prototype并不是father对象,所以没有name属性),这时再设置child.prototype为new father()已经错失了赋予那个空对象任何father的属性的时机了(形象的来说就是:对象都已经建好了,再给构造函数设置prototype有个鸟用,留给下一个对象用吧!)。所以,liangws后来加的var son1=new child()就能有这个name属性就是这个原因。最后,构造函数执行完,也就是构造好原来那个空对象后,就接着将这个空对象赋值给变量son,整个对象创建的过程完成。所以我原来的代码其实等同于:

<script type="text/javascript">
var father=function(){
this.name="father";
}
var child=function(){
//child.prototype=new father();//放到外面,在son对象创建后执行
}

var son=new child();
child.prototype=new father();//在son已经创建后执行,再来设置son的构造函数的prototype已经对son没有任何意义了,son不会回过头来继承father任何成员。
alert(child.prototype.name);
alert(son.name);
</script>

liangws 2011-11-19
  • 打赏
  • 举报
回复
楼主试试?简单来说。引擎在new的时候会先将prototype的引用放到实例中,然后再执行构造函数里面的code..你第一次new的时候child.prototype=new father();还没执行,引擎就将prototype的引用放到实例中了。所以son没有name这个属性。。第二次new的时候,在第一次的child.prototype=new father();已经执行了,所以son1有name
var father=function(){
this.name="father";
}
var child=function (){
child.prototype=new father();
}
var son=new child();

alert(child.prototype.name);
alert(son.name);

var son1=new child();
alert(son1.name);

wyman25 2011-11-19
  • 打赏
  • 举报
回复
谢谢liangws,有空请再指教提点一下,谢谢。
liangws 2011-11-19
  • 打赏
  • 举报
回复
3楼明显是错的,楼主,我现在有点忙,空闲的时候再解释
代码改一下


var father=function(){
this.name="father";
}
var child=function(){
// child.prototype=new father();
child.prototype.name = "123"; //改变副本,不改变引用,
}
var son=new child();
alert(child.prototype.name);
alert(son.name);
hexinping123 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dencey 的回复:]
定义类的构造函数时,对原型(prototype)的定义要放在构造函数外部的,否则它只是构造函数的一项属性,而不是类的原型,所以不会被继承,
[/Quote]

3楼的朋友说的对,你把 “child.prototype=new father();”这句代码放到外面,你再画下原型链图,就明白了
默默不得鱼 2011-11-19
  • 打赏
  • 举报
回复
你写在function里时 还没有执行你的继承 child还是child
dencey 2011-11-19
  • 打赏
  • 举报
回复
定义类的构造函数时,对原型(prototype)的定义要放在构造函数外部的,否则它只是构造函数的一项属性,而不是类的原型,所以不会被继承,
wyman25 2011-11-19
  • 打赏
  • 举报
回复
“引擎在new的时候会先将prototype的引用放到实例中,然后再执行构造函数里面的code.”这是什么意思?可以再解析详细一点吗?或者配合一些代码解析一下,谢谢。还有就是liangws兄是在哪里学习到这点的?是js引擎的解析编译,还是js哪个特性?

87,909

社区成员

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

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