Open AwakenedSomeone opened 3 years ago
function foo (num) { console.log('foo:' + num) this.count++ } foo.count = 0 var i; for (i = 0; i < 10; i++) { if (i > 5) { foo(i) } } // foo: 6 // foo: 7 // foo: 8 // foo: 9 // foo被调用了多少次? console.log(foo.count) // 0
上面的例子中,我们假设this指向的是foo函数本身,那么this.count应该和foo.count是一样的,但从打印的结果可以看出来,并不是,this并不是指向了自身。问题来了,那this.count到底++在哪里了?通过对词法作用域的学习可以知道,首先this.count在全局中没有查询到这个变量,则在全局上创建了一个count,并且因为加法运算,this.count最后的值为NaN. 可以理解为此时的this指向的是全局,因为foo是在全局调用的。 解决办法:显示的将this绑定到函数本身:
function foo (num) { console.log('foo:' + num) this.count++ } foo.count = 0 var i; for (i = 0; i < 10; i++) { if (i > 5) { foo.call(foo, i) // 重点在于这一句,通过call使得this指向函数对象foo本身 } } // foo: 6 // foo: 7 // foo: 8 // foo: 9 // foo被调用了多少次? console.log(foo.count) // 4
需要明确一点:this在任何情况下都不指向函数的词法作用域(因为this是在运行时进行绑定的,类似于动态作用域) 举个栗子:
function foo() { var a = 2; this.bar() } function bar() { console.log(this.a) } foo() // undefined
这段代码通过this.bar()能调用成功,是因为foo是在全局调用的,所以this.bar能找到,然后执行打印,但是this.a在全局中找不到,所以创建了一个a,值为undefined。它并不会像词法作用域那样找到foo里的a = 2,不能试图通过this联通foo和bar的词法作用域。 2.总结: this是在运行时进行绑定的,并不是在编写时绑定,它指向什么完全取决于函数在哪里被调用。
上面的例子中,我们假设this指向的是foo函数本身,那么this.count应该和foo.count是一样的,但从打印的结果可以看出来,并不是,this并不是指向了自身。问题来了,那this.count到底++在哪里了?通过对词法作用域的学习可以知道,首先this.count在全局中没有查询到这个变量,则在全局上创建了一个count,并且因为加法运算,this.count最后的值为NaN. 可以理解为此时的this指向的是全局,因为foo是在全局调用的。 解决办法:显示的将this绑定到函数本身:
需要明确一点:this在任何情况下都不指向函数的词法作用域(因为this是在运行时进行绑定的,类似于动态作用域) 举个栗子:
这段代码通过this.bar()能调用成功,是因为foo是在全局调用的,所以this.bar能找到,然后执行打印,但是this.a在全局中找不到,所以创建了一个a,值为undefined。它并不会像词法作用域那样找到foo里的a = 2,不能试图通过this联通foo和bar的词法作用域。 2.总结: this是在运行时进行绑定的,并不是在编写时绑定,它指向什么完全取决于函数在哪里被调用。