you think you know javascript?
学了两个多月,一些基本概念还是没搞清,要加把劲了。直接上题(题目出处,大叔系列),有几题我做了点补充,答案放后面,还没做过的同学可以先自己思考思考。
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);
a = 1; //补充题
alert(a);
function b(x, y, a) { arguments[2] = 10; alert(a); } b(1,2,3); b(1,2); //补充题
function a() { alert(this); } a.call(null);
1.变量声明和函数声明(函数表达式不会)会放在范围作用域的顶部,也就是在进入上下文的时候就声明了。而作为全局变量的a同时也是window的属性,因此'a' in window是true,相当于声明了a没有给它赋值,输出为undefined。
2.一般我们给b的是一个匿名函数,这里函数不再匿名而有了名字a,前面提到过,函数表达式不会预解析,不仅如此,变量对象VO中也不会包含函数表达式。我们详细看一下过程,进入上下文时:VO = {a: undefiend, b:undefined},代码执行时:VO={a: 1, b: <reference to FunctionExpression "a">}。输出为1。PS:据说IE浏览器在这里会把a当作函数声明,然后被变量赋值覆盖了,因此如果执行到a(--x)是会报错的,如果在后面加上b(2);会报错,而其他浏览器在函数外面的a是数字,函数内的a还是函数本身,执行b(2);的话返回undefined。我现在是Edge浏览器,并没有出现报错的问题,有兴趣的同学可以自己试试。
3.有一个规则,那就是函数声明会覆盖掉变量对象里已存在的同名属性,而变量声明不会干扰变量对象里已存在的同名属性。另一个规则就是给变量赋值的话会覆盖函数声明。在变量对象的世界里,变量声明是最低等的,如果在活动对象AO中,遇到同名的函数声明和形参它都要让道,不过一旦变量赋值后,就成为最厉害的了,同名的函数和形参都要给它让道。显然,第一个alert输出函数,第二个输出1。
4.a和arguments[2]之间是什么关系呢,它们并不共享同一个内存地址,是分别在两个不同的内存地址,而JS引擎会保证它们两个的值保持随时一致,所以b(1,2,3)输出10。但这有个前提,就是arguments的索引值得小于实际传入的参数个数,即如果是b(1,2),那么a和arguments[2]的值就不再保持一致了,b(1,2)输出undefined。
5.第五题就比较简单了,是[object Window]。