1.为什么使用this
function identify() { return this.name.toUpperCase(); } function speak() { var greeting = "Hello,I'm" + identify.call(this); console.log(greeting); } var me = { name: 'tianyuanfeng' }; var you = { name: 'Reader' }; identify.call(me); identify.call(you); speak.call(me); speak.call(you);复制代码
如果不使用this,就需要显示传入一个上下文对象
function identify(context) { return context.name.toUpperCase(context); } function speak(context) { var greeting = "Hello,I'm" + identify(context); } identify(you); speak(me);复制代码
使用this, 隐式传递一个对象引用,使API更加简洁易用
显示传递会使代码变得越来越乱,使用this则不会这样。 使用对象,原型,就会明白函数自动引用合适的上下文对象是很重要的。
2.this的误解
两种常见的对于this的解释都是错误的
2.1 指向自身
存储状态(属性的值) this并不是指向函数对象,虽然属性名相同,但是根对象却并不相同
function foo(num) { document.write('foo: ' + num +''); // 记录foo被调用的次数 this.count++; } foo.count = 0; var i; for (i = 0; i < 10; i++) { if (i > 5) { foo(i); } } document.write(foo.count);复制代码
回避这个问题,回到舒适区,采用词法作用域。无法理解 this的含义和工作原理
function foo(num) { document.write('foo:' + num + ''); data.count++; } var data = { count: 0 }; var i; for (i = 0; i < 10; i++) { if (i > 5) { foo(i); } } document.write(data.count)复制代码
function foo() { foo.count = 4; // 具名函数,内部使用foo来引用自身 } setTimeout(function() { // 匿名函数无法指向自身 });复制代码
回避this问题,完全依赖变量foo的词法作用域
function foo(num) { document.write('foo:' + num + ''); foo.count++;}foo.count = 0;var i;for (i = 0; i < 10; i++) { if (i > 5) { foo(i); }}document.write(foo.count);复制代码
强制this指向foo函数对象, 使用了this
function foo(num) { document.write('foo: ' + num + ''); this.count++;}foo.count = 0;var i;for (i = 0; i < 10; i++) { if (i > 5) { foo.call(foo, i); }}document.write(foo.count);复制代码
2.2 指向函数的词法作用域
this指向函数的作用域 当把this与词法作用域的查询混合使用的时候,一定要提醒自己,这是无法实现的
3.this到底是什么
this是运行时进行绑定的,而不是编译的时候 this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用