打印

【出题】javascript的小小考题

复制内容到剪贴板
代码:
<script>
function foo(){
  foo.abc = function(){alert('def')}
  this.abc = function(){alert('xyz')}
  abc = function(){alert('@@@@@')};
  var abc = function(){alert('$$$$$$')}
}
foo.prototype.abc = function(){alert('456');}
foo.abc = function(){alert('123');}
var f = new foo();
f.abc();
foo.abc();
abc();
</script>
请尽量不执行,试着直接给出结果并给出理由

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

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

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

[ 本帖最后由 Sheneyan 于 2007-7-28 17:28 编辑 ]
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~
看不懂
能不能每条加上注释啊
[wma]http://jie.splan.cn/ggldl/梅艳芳.mp3[/wma]
老大一直就这么神密@)(@

TOP

认证您的手机,获得手机认证图标, 更多手机认证的好处
另存,运行,没有任何反应..
博客又挂了
Never give up hope
经典站长联盟QQ群:16719484 PHPERQQ群:85363040
第七行少了一个括号吧,

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

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

TOP

呵呵
先给你找个错误吧

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

TOP

啊  哦

晚了一步

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


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

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

TOP

那个右大括号的漏写不是问题所在,是我笔误……不需要纠缠那个问题了,继续研究这段无聊的代码吧
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP

作用域??倒底在搞虾米东东嘛..
博客又挂了
Never give up hope
经典站长联盟QQ群:16719484 PHPERQQ群:85363040

TOP

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

foo.abc = function(){alert('def')} 前没var 应该是全局变量吧.
博客又挂了
Never give up hope
经典站长联盟QQ群:16719484 PHPERQQ群:85363040

TOP

我来说说自己的想法,请版主指点
var f = new foo(); //新建了一个foo对象,注意这时个上下文环境到了foo()中
f.abc();      //查找这个对象的abc()方法,输出xyz, 注意如果找不到就会去f.prototype里找,到那时才会输出456
foo.abc();              //在foo()中找到abc()方法,输出def, 如果找不到会跳出foo() 到外面找到abc ,输出123
abc();                    //在foo()中找到abc()方法, 输出@@@@@

TOP

运行结果:

xyz

def     

nothing output
Family comes first!

TOP

引用:
原帖由 blueken 于 2007-7-28 14:54 发表
我来说说自己的想法,请版主指点
var f = new foo(); //新建了一个foo对象,注意这时个上下文环境到了foo()中
f.abc();      //查找这个对象的abc()方法,输出xyz, 注意如果找不到就会去f.prototype里 ...
最后一个好像解释的不对吧
Family comes first!

TOP

我突然发现,我是在第七行加}的,如果在第五行加,最后一个就报错了。。。。

TOP

为什么第二个输出 def
不懂
greengnn's space W3C技术资料 WEB标准群:46077068 西安BI会员群:63970757

TOP

嗯嗯,我想下周再揭秘(其实也只是说出我自己的看法而已),这样比较有意思。

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

@wuleying,veking:没理由哈~
@blueken:嗯,结果,理由都写了,先表扬一下 ,你可以去试试运行结果,不过不要贴出来哈,也不要偷偷修改你的结果,等我下周揭秘时再来提问
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP

版大 开始吊我们的胃口啦。
好,下周一我要看结果


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

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

TOP

:confused:

努力,努力

TOP

我上面答的有问题。哈哈,我已经想通啦

TOP

呵呵,补充一个问题,其实是之前题目中就已经隐藏的,不过似乎没人意识到:

我的代码最后一行可能会抛错(指ie,其他浏览器我不确定是否会出错!),为什么?如何在只删除一行的情况下不让它抛错?为什么?
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP

呵呵,越来越有意思啦。。。

我喜欢!!!

////////////////////////////////////
先分析一下出什么错误,用error捕捉错误显示 (TypeError 缺少对象)错误,原来是这样,只要知道什么错误就好办了。
错误分析代码如下:
复制内容到剪贴板
代码:
...
try{
    abc();
}catch(e){
    alert(e.name+"\n"+e.message);
}
关于楼主要求删除一行就解决错误,那就很简单了,删除abc();

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

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

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

TOP

正确做法应该是删除

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

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


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

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

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

TOP

呵呵,继续扩展:

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

为什么这么做?

[ 本帖最后由 Sheneyan 于 2007-7-28 17:15 编辑 ]
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP

回复 #15 greengnn 的帖子

同问。。这个真的不懂,想不明白!
态度决定一切 电影下载

TOP

f.abc();  >> 456
foo.abc();  >> 123
abc();  >> 报错
Simple is Beauty...

TOP

粗心犯得错啊...
prototype的定义是在new之前
惭愧+虚心学习
Simple is Beauty...

TOP

一点也看不懂!

TOP

复制内容到剪贴板
代码:
<script>
function foo(){
  foo.abc = function(){alert('def')}
  this.abc = function(){alert('xyz')}
  abc = function(){alert('@@@@@')};
  var abc = function(){alert('$$$$$$')}
}
foo.prototype.abc = function(){alert('456');}
foo.abc = function(){alert('123');}
var f = new foo();
f.abc();
foo.abc();
abc();
</script>
首先必须明白的是
这一段代码,是函数重载了很多次,只是定义函数了,并没有执行函数。javascript中同一函数总是以后面的那一个为准
复制内容到剪贴板
代码:
<script>
1.   function foo(){
2.     foo.abc = function(){alert('def')};
3.     this.abc = function(){alert('xyz')};
4.     abc = function(){alert('@@@@@')};
5.     var abc = function(){alert('$$$$$$')};
6.   }
7.   foo.prototype.abc = function(){alert('456');};
8.   foo.abc = function(){alert('123');};
9.   var f = new foo();
第一行定义了一个foo类|对象
第二行定义了一个foo对象的属性abc这个属性(或方法)是一个函数对象
第三行使用了this关键词指代foo对象,所以这里foo.abc属性(或方法)重载了一次
第四行定义了一个abc局部函数,并非foo的属性(或方法)。
第五行将局部函数abc重载了一次

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

再看执行函数结果
复制内容到剪贴板
代码:
f.abc();
foo.abc();
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

TOP

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

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

 提示:您可以先修改部分代码再运行
在分析一下代码
复制内容到剪贴板
代码:
<script>
1. var foo = function(){};
2. foo.prototype.abc = function(){alert('456');};
3. foo.abc = function(){alert('123');};
4. var f = new foo();
5. f.abc();
6. foo.abc();
</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 编辑 ]

TOP

呵呵,楼上两位兄弟的分析很全面,虽然似乎意见不同,不过都蛮有意思的哦~

大家继续~~

另:cssxp你的疑问思考完了没?
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP