# 代码输出值(this/自调用/闭包)
在群里看到了一个挺有意思的面试题,第一感觉是:又是哪来的SB面试官
结果还是低头面对现实吧,指不定哪天面试遇到了,做不出来就尴尬了
var x = 2;
var y = {
x: 3,
z: (function(x){
this.x *= x;
x += 2;
return function(n){
this.x *= n;
x += 3;
console.log(x)
}
})(x)
}
var m = y.z
m(4)
y.z(5)
console.log(x, y.x)
// 7
// 10
// 16 15
下面来分析一下过程:
# 分析一
一开始,在定义 对象y
的时候,y对象的属性z的值是一个自执行函数,参数为window.x
- 自调用函数的 this 指向 window
- 执行第一步,此时全局的
x = 4
- 传入的参数+2,参数
x = 4
- 最后返回函数,形成了闭包,也就是外部的
x += 2
,最终是x = 4
var x = 2;
(function(x){
this.x *= x; // 第一步
x += 2; // 第二步
return function(n){
this.x *= n;
x += 3;
console.log(x)
}
})(x)
# 分析二
先是把 y.z 赋值给 m,再调用函数 m(4),所以这里的 this 指向 window,this永远指向调用的最后一个对象
- 第一步的x为
window.x
,经由分析一得出window.x = 4 * 4 = 16
- 由分析一得出这里是一个闭包,闭包存在
x = 4
,所以这里的x += 3
等于x = 4 + 3 = 7
var x = 2;
z: (function(x){
this.x *= x;
x += 2;
return function(n){
this.x *= n; // 第一步
x += 3; // 第二步
console.log(x)
}
})(x)
var m = y.z
m(4) // 7
# 分析三
很明显,这里的 this 指向就是 y对象 了,所以,这里的 this.x *= n
等于 y.x *= n
等于 y.x = 15
接着第二步还是闭包,由分析二得出的,闭包 x = 7
,所以 x= 3+7 = 10
var x = 2;
var y = {
x: 3,
z: (function(x){
this.x *= x;
x += 2;
return function(n){
this.x *= n; // 第一步
x += 3; // 第二步
console.log(x)
}
})(x)
}
y.z(5) // 10
console.log(x, y.x) // 16 15