this关键字
this是什么
this关键字是JavaScript中最复杂的机制之一。它是一个特别的关键字,被自动定义在所有函数的作用域中。但是即使是非常有经验的JavaScript开发者也很难说清它到底指向什么。
实际上,JavaScript中this的机制并没有那么先进,但是开发者往往会把理解过程复杂化。不理解它的含义,大部分开发任务都无法完成。
this都有一个共同点,它总是返回一个对象。简单说,this就是属性或方法”当前“所有对象。
var person = {
name : '派大星',
describle : function(){
return '姓名:'+this.name;
}
}
person.describle();//姓名:派大星
为什么使用this
this提供了一个很优雅的方式来隐式”传递“一个对象引用,因此将API设计的更加简洁并且易于复用。
随着你的使用模式越来越复杂,显示传递上下问对象会让代码变得越来越混乱,使用this则不会这样。
function identify(){return this.name.toUpperCase();}
function speak(){
console.log("Hello,I'm"+ identify.call(chis));
}
var me = {name : "Kyle"};
var you = {name : "Reader"};
identify.call(me);
identify.call(you);
speak.call(me);
speak.call(you);
调用位置
想要了解this绑定过程,首先要了解调用位置:调用位置就是函数在代码中被调用的位置(而不是声明的位置);
通常来说,寻找调用位置就算寻找“函数被调用的位置”。最重要的是要分析调用栈(就是为了到达当前执行位置所调用的所有函数)。
function baz(){
//当前调用栈是:baz。因此,当前调用位置是全局作用域
console.log("baz");
bar();//<-bar 的调用位置
}
function bar(){
//当前调用栈是baz->bar。因此,当前调用位置在baz中
console.log("bar");
}
baz();//<-baz 的调用位置
注意this的使用
避免多层this
多层函数或方法嵌套可能导致不同层次的this绑定的对象不同,如下实例代码所示:
var o = {
f1 : function(){
console.log(this);
var f2 = function(){
console.log(this);
}();
}
}
o.f1();
上面代码包含两层this,结果运行后,第一层指向对象o,第二层指向全局对象。
避免数组方法中的this
数组的map和foreach方法,允许提供一个函数作为参数。这个函数内部不应该使用this。
var o = {
v : 'hello',
p : function f(){
this.p.forEach(function(itern){
console.log(this.v +' '+item );
});
}
}
o.f();
上述代码中,foreach方法的回调函数中的this,其实是指向全局对象,因此取不到o.v的值。
避免在回调函数中的this
回调函数中的this经常会改变绑定对象,最好的解决方案就是避免这样的使用this。
var o = {
name : '海绵宝宝'
}
o.fn = function(){
console.log(this.name);
}
var name = '制作蟹皇堡';
function f(v){
v();
}
f(o.fn);
上面代码中,f()方法的回调函数中的this,其实是指向全局对象。