VisYang's Studio.

函数内部 this 指向 & 改变指向的方法

2015/09/20
this是函数内部的一个自动生成的对象,随着使用场景的不同,this的指向也不同,下面列举一些this指向的事例。

事件处理函数内部的 this

事件处理函数内部 this 指向 事件源 DOM 对象

1
2
3
4
5
6
7
8
9
10
11
12
var lis = document.querySelectorAll('li');
//事件处理函数内部的 this 始终都是点击的事件源 DOM 对象
lis.forEach(function (li) {
li.addEventListener('click', function () {
console.log(this); // 事件源 DOM 对象
var that = this;
setTimeout(function () {
console.log(this, that); // this--Window
}, 1000);
});
});

定时器函数内部的 this & 普通函数内部的 this

定时器函数内部 this 指向 window
普通函数内部 this 指向 window

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 定时器函数内部的 this 都是 window
setTimeout(function () {
console.log(this); //window
}, 1000);
function fn () {
// 如果在函数内部调用一个普通函数,该函数内部的 this 指向的是 window
console.log(this); // 指向 window
var handle = function (item, index) {
console.log(this); // window
};
// 数组遍历方法内部的 this 都指向 window
;[1, 2, 3].forEach(handle);
};
fn();

构造函数中 this

构造函数中 this 指向实例对象

1
2
3
4
5
6
7
8
9
10
function fn(){};
fn.prototype.sayHello = function () {
console.log(this);
};
//谁来点儿这个 sayHello 则内部 this 就指向谁
fn.prototype.sayHello(); //指向原形对象
var instance = new fn();
instance.sayHello(); // 指向实例对象

对象中函数 this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function fn(){
console.log(this);
};
var obj = {
foo: 'hello',
sayFoo: fn,
sub: {
foo: 'world',
sayFoo: fn
};
};
// 指向 obj 自己
obj.sayFoo();
// 这里指向的 sub 谁来点儿 sayFoo 则 this 就指向谁
obj.sub.sayFoo();
fn(); //window
new fn(); //实例对象
// 对象.fn() 谁来点儿就指向谁

当然,还有其他情况可以改变函数内部 this 指向–>函数的call、apply、bind方法

函数的call方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function fn(){
console.log(this);
};
var obj={foo:'bar'};
fn.call(this); //window
//函数的call方法可以改变内部this指向然后调用该函数
fn.call(obj); //obj={foo:'bar'}
function Person(){
fn.call(this);
};
Person(); //window
new Person(); //Person实例对象
//借用数组方法
//把伪数组转为数组:
function fn(){
console.log(arguments);
var args=[].slice.call(arguments,0); //借用数组的slice方法
args.forEach(function(item,index){
console.log(item,index);
});
};
fn(21,41,56,62,2,5);

函数的apply方法

1
apply方法和call方法作用一样,区别在于call传入的参数是单个元素,而apply传入的参数是一个数组。

函数的bind方法

1
2
3
4
5
6
7
8
9
//bind也是用来改变函数内部this的指向,但是它不调用,而是返回一个指定了this环境的新函数。
var obj = {foo:'bar'};
function fn(x,y,z){
console.log(this,x,y,z);
};
var newFn=fn.bind(obj,1);
newFn(4,5);
//bind 可以传参数但是不调用,得到bind之后的新函数在调用的时候也可以传参数
//当你在调用通过bind得到的新函数的时候,实际上会把你在bind时传递的参数和你调用的新函数传递的参数合并,然后作为函数的参数
CATALOG
  1. 1. 事件处理函数内部的 this
  2. 2. 定时器函数内部的 this & 普通函数内部的 this
  3. 3. 构造函数中 this
  4. 4. 对象中函数 this
  • 当然,还有其他情况可以改变函数内部 this 指向–>函数的call、apply、bind方法
    1. 1. 函数的call方法
    2. 2. 函数的apply方法
    3. 3. 函数的bind方法