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 +'<br>');
// 记录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 + '<br>');
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 + '<br>');
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 + '<br>');
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实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用