关于JavaScript作用域的习题和解析

题一:

function Foo(){

var i=0;
return function(){
document.write(i++);
}
}
var f1=Foo();
f2=Foo();
f1();
f1();

f2();

//输出的结果是 0 1 0

解析:这是一个闭包,闭包的作用有两个,一是可以读取函数内部的变量,二是让这些变量的值始终保存在内存中。当f1()和f2()调用时,会创建两个执行环境,保存各自的变量对象,之间是没有相互影响的。而同一个函数多次调用时返回值会被保存到同一个变量对象中,因为闭包i会保存在内存中没有被释放。另外i++是先调用再+1,++i是先+1再调用,所以输出为 0 1 0。


题二:

var A={n:4399};
var B=function(){this.n=9999};
var C=function(){var n=8888;};
B.prototype=A;
C.prototype=A;
var b=new B();
var c=new C();
A.n++;
console.log(b.n);

console.log(c.n);

//输出为 9999 4400

理解:由题目可知,BC的原型都指向A;b c 分别是B C的实例;然后A的n进行了一次自增,再分别调用两个实例对象看看输出n的值是多少。

解析:首先我们要知道new运算的具体执行过程:

         (1)创建一个空对象

         (2)把这个空对象的_proto_指向构造函数的prototype

         (3)把这个空对象赋值给this

         (4)执行构造函数内的代码

       所以当执行var b=new B()时,此时的this指向了新对象,this.n=9999等价于b.n=9999,然后访问b.n,在查找b.n时首先是查找b对象自身有没有n属性,如果没有再去原型(prototype)上找,这里存在,所以返回9999;

       同理,执行var c=new C()时,由于C()函数中只是定义了一个私有变量var n=8888,并没有为对象执行任何操作,也就是说这个变量属性没有绑定到new出来的对象c上,所以c实例中不存在名字为n的属性。因此,c.n会访问原型中的n属性。


题三:

var color='green';
var test4399={
color:'blue',
getColor:function(){
var color='red';
alert(this.color);
}
}
var getColor=test4399.getColor;
getColor();

test4399.getColor();

//输出 green blue

解析:

考察点一:js函数调用时加括号和不加括号的区别,加括号是把函数返回值赋给等号左边,而不加括号相当于把函数代码赋给等号左边。所以代码var getColor=test4399.getColor;相当于var getColor=function(){var color='red';alert(this.color);}

考察点二:js中this的用法,this总是指向调用它的对象。所以getColor();执行时,相当于Windows调用的,this指向Windows,所以找到的是全局变量中的color,为green。同理,test4399.getColor()是test4399调用的,this指向test4399,所以找的是test4399里的color,为blue。


题四:

function test(){
var n=4399;
function add(){
n++;
console.log(n);
}
return {
n:n,
add:add
}
}
var result=test();          //设置result的属性为:{n:4399,add:add()}
var result2=test();       //设置result2的属性为:{n:4399,add:add()}

result.add();                //调用result的add方法,执行n++,所以n=4399+1=4400,输出4400

result.add();                //再次调用result的add方法,此时n=4400,所以执行n++后,所以n=4401
console.log(result.n);  //这是输出result属性n的值,所以输出4399

result2.add();              //调用result2的add方法,此时n=4399,所以执行n++后,所以n=4400

//输出 4400 4400 4399 4400

解析:这里主要理解result和result2两个实例执行时的作用域不同,互不相关。其他解析见上注释。

===========================================================

今天先更新这几题,以后遇上还会补充的,如有不妥当之处,欢迎指出修改。

猜你喜欢

转载自blog.csdn.net/ariel_201311/article/details/79917365