请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 16874|回复: 58

【出题】javascript的小小考题 [复制链接]

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-28 14:21:15 |显示全部楼层
  1. <script>
  2. function foo(){
  3.   foo.abc = function(){alert('def')}
  4.   this.abc = function(){alert('xyz')}
  5.   abc = function(){alert('@@@@@')};
  6.   var abc = function(){alert('$$$$$$')}
  7. }
  8. foo.prototype.abc = function(){alert('456');}
  9. foo.abc = function(){alert('123');}
  10. var f = new foo();
  11. f.abc();
  12. foo.abc();
  13. abc();
  14. </script>
复制代码


请尽量不执行,试着直接给出结果并给出理由

-------------------
补充了两句

------------------
谢谢楼下的兄弟-。-
笔误-。-

-----------------
编辑了一下题目

[ 本帖最后由 Sheneyan 于 2007-7-28 17:28 编辑 ]
西部数码顶级域名注册商39元抢注!

心肠大大滴好

荣誉管理

帖子
1221
体力
9084
威望
4
发表于 2007-7-28 14:25:38 |显示全部楼层
看不懂
能不能每条加上注释啊
[wma]http://jie.splan.cn/ggldl/梅艳芳.mp3[/wma]
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

wgh001 
帖子
373
体力
752
威望
1
居住地
福建省 厦门市
发表于 2007-7-28 14:38:29 |显示全部楼层
老大一直就这么神密@)(@

使用道具 举报

罗亮

超级版主 手机认证 

帖子
15866
体力
19458
威望
19
居住地
北京市 海淀区
发表于 2007-7-28 14:41:56 |显示全部楼层
另存,运行,没有任何反应..

使用道具 举报

帖子
18
体力
37
威望
0
发表于 2007-7-28 14:43:01 |显示全部楼层
第七行少了一个括号吧,

-----
谢了。。。我少按了两下-。-
by 子乌

[ 本帖最后由 blueken 于 2007-7-28 14:48 编辑 ]

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 14:46:08 |显示全部楼层
呵呵
先给你找个错误吧

abc = function(){alert('@@@@@');
Family comes first!

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 14:46:48 |显示全部楼层
啊  哦

晚了一步

/////////////////////////////////////////////////


f.abc();        //output xyz
foo.abc();        //output xyz
abc();        //nothing output

[ 本帖最后由 veking 于 2007-7-28 14:49 编辑 ]
Family comes first!

使用道具 举报

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-28 14:47:26 |显示全部楼层
那个右大括号的漏写不是问题所在,是我笔误……不需要纠缠那个问题了,继续研究这段无聊的代码吧

使用道具 举报

罗亮

超级版主 手机认证 

帖子
15866
体力
19458
威望
19
居住地
北京市 海淀区
发表于 2007-7-28 14:48:43 |显示全部楼层
作用域??倒底在搞虾米东东嘛..

使用道具 举报

罗亮

超级版主 手机认证 

帖子
15866
体力
19458
威望
19
居住地
北京市 海淀区
发表于 2007-7-28 14:51:16 |显示全部楼层
f.abc();       //output xyz
foo.abc();       //output def
abc();       //nothing output

foo.abc = function(){alert('def')} 前没var 应该是全局变量吧.

使用道具 举报

帖子
18
体力
37
威望
0
发表于 2007-7-28 14:54:57 |显示全部楼层
我来说说自己的想法,请版主指点
var f = new foo(); //新建了一个foo对象,注意这时个上下文环境到了foo()中
f.abc();      //查找这个对象的abc()方法,输出xyz, 注意如果找不到就会去f.prototype里找,到那时才会输出456
foo.abc();              //在foo()中找到abc()方法,输出def, 如果找不到会跳出foo() 到外面找到abc ,输出123
abc();                    //在foo()中找到abc()方法, 输出@@@@@

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 14:55:05 |显示全部楼层
运行结果:

xyz

def     

nothing output
Family comes first!

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 14:57:06 |显示全部楼层
原帖由 blueken 于 2007-7-28 14:54 发表
我来说说自己的想法,请版主指点
var f = new foo(); //新建了一个foo对象,注意这时个上下文环境到了foo()中
f.abc();      //查找这个对象的abc()方法,输出xyz, 注意如果找不到就会去f.prototype里 ...




最后一个好像解释的不对吧
Family comes first!

使用道具 举报

帖子
18
体力
37
威望
0
发表于 2007-7-28 14:58:31 |显示全部楼层
我突然发现,我是在第七行加}的,如果在第五行加,最后一个就报错了。。。。

使用道具 举报

酒酣几度

荣誉管理 手机认证 

帖子
1367
体力
3521
威望
127
发表于 2007-7-28 14:59:10 |显示全部楼层
为什么第二个输出 def
不懂
blog Web标准化交流会 WEB标准群:23783439

使用道具 举报

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-28 14:59:35 |显示全部楼层
嗯嗯,我想下周再揭秘(其实也只是说出我自己的看法而已),这样比较有意思。

to 楼上几个回答了的同学:

@wuleying,veking:没理由哈~
@blueken:嗯,结果,理由都写了,先表扬一下 ,你可以去试试运行结果,不过不要贴出来哈,也不要偷偷修改你的结果,等我下周揭秘时再来提问

使用道具 举报

帖子
18
体力
37
威望
0
发表于 2007-7-28 15:02:00 |显示全部楼层
版大 开始吊我们的胃口啦。
好,下周一我要看结果


------------
我可没说是下周一给出结果,看有多少人回了,人多的话就晚一点,没什么人的话早点出结果也没什么。

[ 本帖最后由 Sheneyan 于 2007-7-28 15:11 编辑 ]

使用道具 举报

帖子
5
体力
22
威望
0
发表于 2007-7-28 15:04:56 |显示全部楼层

:confused:

努力,努力

使用道具 举报

帖子
18
体力
37
威望
0
发表于 2007-7-28 16:06:54 |显示全部楼层
我上面答的有问题。哈哈,我已经想通啦

使用道具 举报

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-28 16:12:07 |显示全部楼层
呵呵,补充一个问题,其实是之前题目中就已经隐藏的,不过似乎没人意识到:

我的代码最后一行可能会抛错(指ie,其他浏览器我不确定是否会出错!),为什么?如何在只删除一行的情况下不让它抛错?为什么?

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 16:16:03 |显示全部楼层
呵呵,越来越有意思啦。。。

我喜欢!!!

////////////////////////////////////
先分析一下出什么错误,用error捕捉错误显示 (TypeError 缺少对象)错误,原来是这样,只要知道什么错误就好办了。
错误分析代码如下:
  1. ...
  2. try{
  3.         abc();
  4. }catch(e){
  5.         alert(e.name+"\n"+e.message);
  6. }
复制代码


关于楼主要求删除一行就解决错误,那就很简单了,删除abc();

就解决了,直接从根本上解决。 嘿嘿

不知道是不是这样解决呢???  

[ 本帖最后由 veking 于 2007-7-28 16:26 编辑 ]
Family comes first!

使用道具 举报

veking 

蓝色水

银牌会员

帖子
299
体力
1246
威望
1
发表于 2007-7-28 16:35:07 |显示全部楼层
正确做法应该是删除

var abc = function(){alert('$$$$$$')}

abc(); //output @@@@@


////////////////////////////////////////////////////

加上原因:
不加 var 默认是全局变量,所以abc();可以正确输出@@@@@,加 var 后,因为是在函数内部,所以从外部无法访问。

[ 本帖最后由 veking 于 2007-7-29 12:13 编辑 ]
Family comes first!

使用道具 举报

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-28 17:06:46 |显示全部楼层
呵呵,继续扩展:

如何在尽可能不修改代码结构以及删除现有函数的情况下让最后一个abc输出@@@@而不是出错或者输出$$$

为什么这么做?

[ 本帖最后由 Sheneyan 于 2007-7-28 17:15 编辑 ]

使用道具 举报

经典会员

金牌会员

帖子
1238
体力
3352
威望
1
发表于 2007-7-28 17:43:55 |显示全部楼层

回复 #15 greengnn 的帖子

同问。。这个真的不懂,想不明白!
态度决定一切 那飞的...

使用道具 举报

帖子
65
体力
185
威望
0
居住地
湖北省 武汉市
发表于 2007-7-28 23:20:10 |显示全部楼层
f.abc();  >> 456
foo.abc();  >> 123
abc();  >> 报错
Simple is Beauty...

使用道具 举报

帖子
65
体力
185
威望
0
居住地
湖北省 武汉市
发表于 2007-7-28 23:22:23 |显示全部楼层
粗心犯得错啊...
prototype的定义是在new之前
惭愧+虚心学习
Simple is Beauty...

使用道具 举报

sarten

高级会员

帖子
563
体力
904
威望
2
居住地
安徽省 合肥市
发表于 2007-7-29 19:03:23 |显示全部楼层
一点也看不懂!

使用道具 举报

hero4u 

孤竹林

金牌会员 手机认证 

帖子
1305
体力
3444
威望
14
居住地
湖南省 长沙市
发表于 2007-7-29 21:11:30 |显示全部楼层
  1. <script>
  2. function foo(){
  3.   foo.abc = function(){alert('def')}
  4.   this.abc = function(){alert('xyz')}
  5.   abc = function(){alert('@@@@@')};
  6.   var abc = function(){alert('$$$$$$')}
  7. }
  8. foo.prototype.abc = function(){alert('456');}
  9. foo.abc = function(){alert('123');}
  10. var f = new foo();
  11. f.abc();
  12. foo.abc();
  13. abc();
  14. </script>
复制代码


首先必须明白的是
这一段代码,是函数重载了很多次,只是定义函数了,并没有执行函数。javascript中同一函数总是以后面的那一个为准
  1. <script>
  2. 1.   function foo(){
  3. 2.     foo.abc = function(){alert('def')};
  4. 3.     this.abc = function(){alert('xyz')};
  5. 4.     abc = function(){alert('@@@@@')};
  6. 5.     var abc = function(){alert('$$$$$$')};
  7. 6.   }
  8. 7.   foo.prototype.abc = function(){alert('456');};
  9. 8.   foo.abc = function(){alert('123');};
  10. 9.   var f = new foo();
复制代码

第一行定义了一个foo类|对象
第二行定义了一个foo对象的属性abc这个属性(或方法)是一个函数对象
第三行使用了this关键词指代foo对象,所以这里foo.abc属性(或方法)重载了一次
第四行定义了一个abc局部函数,并非foo的属性(或方法)。
第五行将局部函数abc重载了一次

第七行 使用了原型 方法abc,实际上还是重载了foo.abc
第八行 foo.abc又重载了一次
第九行 实例化foo类的一个对象f

再看执行函数结果
  1. f.abc();
  2. foo.abc();
  3. abc();
复制代码


f和foo引用类型指向不是同一个对象 执行结果应该是这样的
第一行 f为foo类的实例,由于最后foo.prototype.abc 重载了一下,所以f继承了这个属性alert('456');
第二行 foo对象的方法abc被重载了一次,所以应该以最后的定义为准alert('123');
第三行 abc()函数应该是undefined。因为它是局部函数。【或者说window.abc()这个方法不存在了】。

为什么第一个跟第二个执行的结果会不一样?
因为在判断的时候将foo类跟foo对象区别开来了。实际上javascript是一门弱变量类型的语言,值就只包括两种,一种是原值,一种是引用类型值。原值就五种类型(undefined null number bool string),引用类型就是指向“原值”的指针了。
定义了foo类,那么从foo派生出来的新对象f应该继承了prototype.abc属性,而没有被覆盖了。还未测试

 提示:您可以先修改部分代码再运行

体验游戏 game4power

使用道具 举报

cssxp 

体验css

中级会员

帖子
207
体力
361
威望
14
发表于 2007-7-29 21:33:28 |显示全部楼层

这是一个关于constructor构造函数和prototype原型函数的问题

先运行这一段代码试试看了

 提示:您可以先修改部分代码再运行



在分析一下代码
  1. <script>
  2. 1. var foo = function(){};
  3. 2. foo.prototype.abc = function(){alert('456');};
  4. 3. foo.abc = function(){alert('123');};
  5. 4. var f = new foo();
  6. 5. f.abc();
  7. 6. foo.abc();
  8. </script>
复制代码

1. 定义一个空的对象foo
2. 扩展foo类的原型属性|方法 abc 由foo类创造的对象都会继承该属性|方法
3. foo对象重载了abc属性|方法|成员
4. 实例化一个foo类的对象f
5. f对象运行结果为 警告456
6. foo.abc()的运行结果为 警告123

为什么会这样?
第一 f对象是由foo类class派生出来的,继承了该foo类的所有属性和方法

第二 凭什么判断 var foo = function(){}; 既是是类且又是对象? 将这一句替换成var foo = new Object(); 运行会出错。foo.prototype has no properties 也就是foo对象不能扩展原型属性,foo类可以了

第三 f对象和foo对象都是引用类型值,指向不是内存里的同一个对象。所以foo.abc = function(){alert('123');}; foo对象的abc方法被重载了,而f.abc没有被重载,因为不是同一个对象。

现在再回过头来看原题目

 提示:您可以先修改部分代码再运行


运行结果为 alert('xyz') 和 alert('def')

为什么又是这样的结果?

第一 为什么f.abc()运行结果是alert('def') foo.abc()运行的结果是 alert('xyz')  ?
foo.abc = function(){alert('def')}; 代表的是实例对象foo的属性|方法abc,foo指向的是foo对象内存地址。this指向的是当前类派生对象的内存地址,所以f.abc被重载了。foo.abc总是指向foo.abc从构造函数中派生了之后就未被重载过了。

验证猜测将foo.abc = function(){alert('def')};与this.abc = function(){alert('xyz')};换一个位置

 提示:您可以先修改部分代码再运行


这一次运行结果f.abc()运行结果是alert('xyz') foo.abc()运行的结果是 alert('def')  


第二 为什么foo.abc = function(){alert('123');};没有将this.abc给重载?

排除干扰把foo.abc = function(){alert('def')};给删除掉

 提示:您可以先修改部分代码再运行


运行结果为 xyz 和 123

第三 为什么foo.prototype.abc不能重载掉函数foo.abc = function(){alert('123');};

 提示:您可以先修改部分代码再运行




等等还有很多疑问了。思考之后再回答这个问题

[ 本帖最后由 cssxp 于 2007-7-29 22:33 编辑 ]

使用道具 举报

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2007-7-30 09:08:08 |显示全部楼层
呵呵,楼上两位兄弟的分析很全面,虽然似乎意见不同,不过都蛮有意思的哦~

大家继续~~

另:cssxp你的疑问思考完了没?

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-4 15:19 , Processed in 0.264508 second(s), 10 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部