概念
- this是指属性和方法当前所在的对象
- 不管什么情况,this总返回一个对象
- 对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的。
- JavaScript 语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this就是函数运行时所在的对象(环境)
使用
- 全局环境
this === window; // true
function f() {
console.log(this === window);
};
f(); // true
不管是不是在函数内部,只要是在全局环境下运行,this就是指顶层对象window
- 构造函数,this代表新建的实例对象
- 对象方法,如果对象的方法里面包含this,this的指向就是方法运行时所在的对象(环境)。
如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。
var o = {
f1: function () {
console.log(this);
var f2 = function () {
console.log(this);
}();
}
};
o.f1();
// Object
// Window
-------------------------------
var temp = function () {
console.log(this);
};
var o = {
f1: function () {
console.log(this);
var f2 = temp();
}
};
注意
- 不要在函数中多层this嵌套使用
- 在外层使用
var that = this;
来固定this,然后内层函数调用这个变量 - 数组处理方法
forEach
中作为参数传入的函数内不要使用this - 回调函数中避免使用this ,会变为触发回调事件的那个对象
var o = new Object();
o.f = function () {
console.log(this === o);
}
// jQuery 的写法
$('#button').on('click', o.f);
绑定
- 箭头函数的使用与不适用场景
- Function.prototype.call(),call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。
function add(a, b) {
return a + b;
}
add.call(this, 1, 2) // 3
- Function.prototype.apply(),apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数
var o = new Object();
o.f = function () {
console.log(this === o);
}
var f = function (){
o.f.apply(o);
// 或者 o.f.call(o);
};
$('#button').on('click', f); // true
apply方法(或者call方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。更简洁的写法是采用bind方法。
- Function.prototype.bind(),用于将函数体内的this绑定到某个对象,然后返回一个新函数
var counter = {
count: 0,
inc: function () {
this.count++;
}
};
var obj = {
count: 100
};
var func = counter.inc.bind(obj);
func();
obj.count // 101
click事件绑定bind方法生成的一个匿名函数。这样会导致无法取消绑定,所以监听事件不要写为:element.addEventListener('click', o.m.bind(o));
正确的方法是写成下面这样:
var listener = o.m.bind(o);
element.addEventListener('click', listener);
// ...
element.removeEventListener('click', listener);
参考:
http://javascript.ruanyifeng.com/oop/this.html