题目:
var n = 2;
var obj = {
n: 30,
fn: (function (n) {
n *= 2;
this.n += 2;
var n = 5;
return function (m) {
this.n *= 2;
console.log(m + (++n));
}
})(n)
};
var fn = obj.fn;
fn(3);
obj.fn(3);
console.log(n,obj.n);
=======考虑下会打印出来什么=======
5
4
3
2
1
公布结果:
9
10
8 60
解析:
第一步:
先看这一段代码
fn内部是个自执行函数,所以此时内部代码已经执行,让我们按照序号看下面代码内的的备注
var n = 2;
var obj = {
n: 30,
fn: (function (n) {
n *= 2; // 2. n=2*2=4
this.n += 2; // 3. n为window.n,值是2*2=4
var n = 5; // 4.n赋值为5
return function (m) { // 5. 返回一个匿名函数
this.n *= 2;
console.log(m + (++n));
}
})(n) //1. 这里的实参取的是var n = 2
};
此时 window.n = 4,并且obj.fn返回了一个匿名函数,并形成闭包内部存留n=5。继续进行
第二步:
var fn = obj.fn; // 没有啥,把obj.fn(即上面的匿名函数) 赋值给一个新的变量
fn(3); // 执行匿名函数
具体内部赋值如下
// 执行该函数 fn(3)
function (m) { // 这里形参m值为传入的3
// console.log(n) 注意这里如果打印n的话,此时n已经是5啦
this.n *= 2; // 执行 fn(3)是调用方为window,所以此时this.n = 4, 计算之后变为8
console.log(m + (++n)); // 这里的n=5, 3+(++5)计算后输出9,此时n=6
}
截止到这里控制台打印出9,此时window.n=8, 让我们继续
第三步
obj.fn(3); // 没啥执行这个函数
内部赋值如下:
function (m) { // 这里形参m值为传入的3
// console.log(n) 注意这里如果打印n的话,此时n已经是6啦
this.n *= 2; // 执行obj.fn(3)是调用方为obj,所以此时this.n = 30, 计算之后变为60
console.log(m + (++n)); // 上一步说了n=6 , 3+(++6) 计算后输出10
}
第四步
console.log(n,obj.n); // 输出这两个变量的值,显而易见此时n=8, obj.n = 60
总结
这道题包含了闭包、this指向、作用域等等问题,还是需要进一步好好消化和理解的~
网友评论