注册 登录
编程论坛 JavaScript论坛

大家先试着给出 alert 语句的输出结果,有积分奖励哦

冰镇柠檬汁儿 发布于 2015-03-14 17:38, 1348 次点击
大家先试着给出 alert 语句的输出结果。能解释出原因的第一个人我给20分奖励,不要自欺欺人到网上搜哦
 一
if (!("a" in window)) {
    var a = 1;
}
alert (a);


var a = 1,
    b = function a (x) {
        x && a (--x);
    };
alert (a);


function a (x) {
    return x * 2;
}
var a;
alert (a);


function b (x, y, a) {
    arguments[2] = 10;
    alert (a);
}
b(1, 2, 3);


function a () {
    alert (this);
}
a.call (null);
16 回复
#2
wmf20142015-03-14 21:42
我回答会不会扫大家的兴?还是留帅哥们去争先恐后吧!
提示:对于少量javascript语句执行,可直接在浏览器地址栏运行调试(不用写html网页)
#3
诸葛欧阳2015-03-14 21:43
不会,看不懂
#4
冰镇柠檬汁儿2015-03-14 21:50
回复 2楼 wmf2014
我可是要结果和解释的哦
#5
wmf20142015-03-14 22:07
我试着回答第一个:由于后面定义了变量a=1并使用了变量,所以a是window的元素,if (!("a" in window)) 条件不成立,alert的结果是undefine。
如果语句为:
if (!("a" in window)) {
    var b = 1;
}
alert (b);
则alert会输出1。

#6
冰镇柠檬汁儿2015-03-14 22:16
回复 5楼 wmf2014
没错,只是解释的不是很清晰,可以再详细一点吗?
也可以继续其他的问题

[ 本帖最后由 冰镇柠檬汁儿 于 2015-3-14 22:18 编辑 ]
#7
wmf20142015-03-14 22:44
回复 6楼 冰镇柠檬汁儿
js "in window"是检索window对象的所有属性和元素,定义的变量和按钮id等都属于window的元素。你代码有var a=1,则说明a已成为window的一个元素,所以("a" in window)=true,而!("a" in window)=false,则var a=1语句没执行(不执行并不妨碍解释器为变量a分配空间)。
还是让帅哥们去费脑筋吧,我其实不太熟悉js。

[ 本帖最后由 wmf2014 于 2015-3-14 22:46 编辑 ]
#8
冰镇柠檬汁儿2015-03-14 23:56
还说不熟悉呢,解释的已经很清楚了
#9
蝙蝠之殇2015-03-17 15:39
第一题和第五题的原理是什么?不是很懂,求楼主解释!
#10
冰镇柠檬汁儿2015-03-17 16:50
等过两天,到期了,我再解释吧
#11
冰镇柠檬汁儿2015-03-17 17:29
第一题答案:undefined
原因:
首先,大家要明白,javascript没有c/c++所谓的块作用域,所以在if、for、while等语句中使用var定义的变量,实际上等同于在这些语句所在的作用域中定义变量。
其次,在javascript代码执行进入某一个作用域时,会先检索所有function和var声明的函数和变量,但不执行var的赋值代码,function也只是简单的开辟一块内存,具体function中怎么执行,需要到调用的时候再去处理。
再次,var a = 1;这句在javascript中是被拆成var a; a = 1;这两句执行的,变量声明后,未赋值时,默认值均是undefined。
这样就造成了一个结果,在if语句执行之前,作用域里就有了a变量的声明,所以"a" in window这句始终是true,当非“!”时,if语句用于为false,而a=1,永远不能被执行。
#12
冰镇柠檬汁儿2015-03-17 17:39
第二题答案:1
var a = 1,
    b = function a (x) {
        x && a (--x);
    };
alert (a);
原因:
首先,大家应该都清楚在javascript中函数声明只有一种方式:即 function a(){...};如果这句放在了等号的右边,那就不再是函数声明,而是函数表达式了。函数声明在代码执行进入作用域时,会先被创建到内存中,而函数表达式则只是执行到该语句时才创建。
其次,函数表达式内部的东西是基本不对外公开的局部变量对象或函数对象。
b = function a (x){...};中,function a实际上是一个函数表达式,并不是真正意义上的函数声明,而a也就成了非对外公开的变量对象,只能在内部访问,对外公开的访问变量对象是b,局部变量不会影响全局变量,所以var a = 1;是不会被影响的。
#13
冰镇柠檬汁儿2015-03-17 17:50
第三题答案:function a(x) { return x * 2; }
这个涉及到javascript定义变量和声明函数的一个原则,先定义或声明一个名称后,再声明同名名称,只要后者不改变值,就会被忽略。
在进入作用域时,先检查定义和声明,对于函数声明,编译器只知道有这么个名称的函数,知道调用时到哪里去找,但内部是什么,编译器不清楚,定义变量也是一样,编译器只知道有这么个变量,值是什么不清楚,但又不能空着,就只好先暂时给个undefined,当名称重复的时候,后面的名称自然会被忽略。
那么,在此题中,var a;自然会被忽略,但是如果写成var a=1;那这个就有了赋值的部分,虽然var定义依然会被忽略,但赋值部分会生效。
#14
冰镇柠檬汁儿2015-03-17 18:12
第四题:
function b (x, y, a) {
    arguments[2] = 10;
    alert (a);
}
b(1, 2, 3);
这个题的另外一个版本是:
function b (x, y, a) {
    arguments[2] = 10;
    alert (a);
}
b(1, 2);
请注意b函数调用时传的参数数量,这一点很重要。
第一个版本的答案是:10
第二个版本的答案是:undefined
结果是不是很令人意外呢?
原因:
每个函数内部作用域中,会对参数传进来的值(例子中就是x,y,a传进来的值)使用一个名叫arguments的数组进行一一对应,传进去多少个值,arguments的长度就有多少,并从0开始一一对应,而参数名的值是和arguments数组共享的,简单的举几个例子可能大家会更容易明白
b(1, 2);,那么x=1,y=2,a没有赋值,自然是undefined,arguments[0]=1,arguments[1]=2,不存在arguments[2]及以后的值(当然你可以自己添加,但是刚进入函数内部作用域时是没有的)
b(1, 2, 3);,那么x=1,y=2,a=3,arguments[0]=1,arguments[1]=2,arguments[2]=3
b(1, 2, 3, 4);,那么x=1,y=2,a=3,arguments[0]=1,arguments[1]=2,arguments[2]=3,arguments[3]=4
大家能从中找到规律吗?
其实就是,当某个参数变量有值传入的时候,参数和arguments的特定值实际上是同一个地址。当没有值传入,或传入过多的参数值时,缺少的部分,不会有arguments的值,
#15
love云彩2015-03-17 18:22
诸葛修勤和寒风中的细雨是大神,他们都比较熟悉javascript
#16
冰镇柠檬汁儿2015-03-17 18:26
第五题答案:[object Window]
function a () {
    alert (this);
}
a.call (null);
这个题涉及到this指针的问题了,而call是每个函数都有的一个调用方式,就是指定函数在什么样的作用域中执行,其中的参数就规定了this指针的指向
function a() {
    alert (this);
}
function c() {
    //do something
};
a.call(c);
如果这样,那么结果就是function c() { },因为已经把this指针指定到了c函数上了,但是如果是null时,this指针会被编译器强行指向全局对象上,在网页中这个对象是window,而在其他情况下是global(这种情况我没遇到过,见笑了),这个全局对象是一个Object对象,所以就有了这样的结果。

至于this指针的问题,我想多解释一句,javascript中的this和C++/C#/JAVA的不同,后者中的this是对象内部的意思,而javascript中this指向的是调用它的作用域,更多的细节,还是问问度娘吧。
#17
冰镇柠檬汁儿2015-03-17 18:29
以下是引用love云彩在2015-3-17 18:22:45的发言:

诸葛修勤和寒风中的细雨是大神,他们都比较熟悉javascript

你确定?有他们的联系方式吗
1