this指向
this是一个指针,指向调用他的对象,它也是一个对象,可以通过this. 调用它的方法,日常用到this主要有这几个方面。
1.全局调用函数
这里调用test()相当于window.test(),所以这里的this指向window。
var x = 2; function test() { console.log(this.x); } test();
2.作为对象属性调用
var o1 = { name: 'zhang', fn1: function () { console.log(this.name); } } o1.fn1();
这里由o1调用fn1(),所以在fn1() 里的this指向调用它的o1,this.name 为zhang。
上面的例子是一层调用,直接对象调用里面的方法,有时候还会有好几层调用。
var o2 = { a: 10, b: { a: 1, fn2: function () { console.log(this.a); } } } o2.b.fn2();
有好几层调用,this指向它的上一级调用的this,所以这里输出a为1。
var o3 = { a: 9, d: { a: 3, fn() { console.log(this.a); } } } var m = o3.d.fn; m();
上面的这个例子,虽然也有好几层调用,但是相当于把fn这个函数赋给m,此时并没有执行,在m()调用才执行,此时调用的环境为 window 所以 this 为window。
function foo() { console.log(this.a) } var obj = { a: 100, foo: foo } var a = 'window global'; setTimeout(obj.foo, 1000)
此处为obj调用foo,但是并没有执行,而是把foo放进任务队列,在foo执行时环境为window,所以this指向window。
3.构造函数中的this
this指向新创建的对象,当new对象时发生了一下四步:
(1)创建一个新对象
(2)将构造函数的作用域赋给新对象(this指向新对象)
(3)执行构造函数代码为对象添加属性
(4)返回新对象
4.call、apply、bind
call与apply的用法相似,call(obj, arg1, arg2),apply(obj, [arg1, arg2])
function foo() { console.log(this.a) } var obj = { a: 3 } var bar = function () { foo.call(obj) } bar(); setTimeout(bar, 1000);
在bar内部手动用call绑定了obj,再用setTimeout也改变不了this指向。
5.箭头函数
普通函数的this指向调用它的对象, 箭头函数的this指向函数定义生效时的对象,准确说箭头函数没有this,它的指向是继承自它的外部代码块,确定了this之后不再被改变。
function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } var id = 21; foo.call({ id: 42 });
反思:我确实存在这个问题,在讲解问题的时候通常只是通过结论直接来讲解,这样不够细致,希望自己在写博客的时候以及日常开发中注意锻炼这方面的能力