// 结合刘小夕小姐姐给的例子 (闭包,this的所有绑定方式都在里面了)
// 如果对答案有疑问,就需要去找原文看看喽
// https://juejin.cn/post/6844903805587619854
var number = 5;
var obj = {
number: 3,
fn1: (function () {
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
}
})()
}
var fn1 = obj.fn1;
fn1.call(null);
obj.fn1();
console.log(window.number);
输出结果为:
10
9
3
27
5
执行结果分析:
-
在定义obj的时候,fn对应的闭包就执行了,返回其中的函数,执行闭包中代码时,显然应用不了new绑定(没有出现new 关键字),硬绑定也没有(没有出现call,apply,bind关键字),隐式绑定有没有?很显然没有,如果没有XX.fn(),那么可以肯定没有应用隐式绑定,所以这里应用的就是默认绑定了,非严格模式下this绑定到了window上(浏览器执行环境)。【这里很容易被迷惑的就是以为this指向的是obj,一定要注意,除非是箭头函数,否则this跟词法作用域是两回事,一定要牢记在心】
fn1 = obj.fn1; // 此时window.number已经因为匿名函数的执行变为了10, // 闭包中的number 此时为3
-
myFun.call(null);我们前面说了,call的第一个参数传null,调用的是默认绑定;
myFun.call(null) // 此时this对象为window, // 输出的num的时候,this对象是window,所以输出为this.number => num: 10, // number是闭包中的number(3) 3*3 = 9
-
obj.fn();应用了隐式绑定,fn中的this对应的是obj.
obj.fn() //此时fn内的this对象指向obj, // 输出num 为obj.number => 3 // 输出number为 闭包中的 9 * 3 => 27
-
最后一步console.log(window.number);输出的结果是20,在匿名函数闭包执行时,已经改变了window.number;
经过两次的this指向window的对象执行,522 = 20