有时候一不写this,就报一个undefined,this的使用简直前端开发的要点啊,this真是无处不在,用的地方简直太多了,尤其是this的指向经常搞得人头晕啊。
this是什么
在面向对象语言中,this是关键字,是对当前对象的引用,而在JavaScript中的this是动态绑定的,或者是运行是绑定的,导致this关键字代表多重含义。
普通函数this
默认指向
- 非严格模式(单独使用 this,则它指向全局(Global)对象。 在浏览器中,window 就是该全局对象为 [object Window])
var x = this;
- 严格模式(如果单独使用,this 也是指向全局(Global)对象。)
"use strict";
var x = this;
方法中使用this
- 简单
var age = 18;
function showAge () {
var age = 98;
console.log('my age is: ' + this.age);
}
showAge();//output:my age is: 18
showAge没有被打点调用,所以指向的是全局对象window,所以this.age就是18。
- 复杂(带有定时器---异步函数)
var age = 18;
var obj = {
age : 98,
showAge : function () {
setTimeout(function () {
console.log('my age is: ' + this.age);
}, 3000);
}
}
obj.showAge();//output:my age is: 18
是不是很惊讶,这不是应该98吗,怎么还是18啊,首先obj.showAge()调用的对象是obj,调用的是showAge()函数,其次setTimeout只是一个定时器不执行(没有被调用),this.age在定时器函数中,所以this的指向还是window,故输出的结果还是18。
构造函数里的this
function Person (name, age) {
this.name = name;
this.age = age;
this.introduceYourself = function () {
console.log('my name is ' + this.name, 'and I\'m ' + this.age + ' years old.');
}
}
var person = new Person('丫蛋', 18);
person.introduceYourself ();//output:my name is
丫蛋 and I'm 18 years old.
call、bind、apply改变this的指向
-
call apply bind 的作用和使用方法 call apply 都是改变一个函数的this指向并执行该函数,区别是传参列表不同,call(obj, 参数1, 参数2, ...) apply(obj, arguments) bind是改变一个函数的this指向并返回一个新的函数,传参结合call和apply的,只接收第一次绑定的this
var obj = {
age : 100,
showAge : function () {
console.log('my age is: ' + this.age);
}
}
var obj2 = {
age : 18
}
obj.showAge.call(obj2);//output:my age is: 18
为什么是18呢?showAge的调用对象明明是obj,但由于用了call,this的指向对象变成了obj2,所以结果为18。
箭头函数this
箭头函数没有this,它的this是继承而来(引用外层的)。
function foo() {
setTimeout(() => {
console.log('Array:', arguments);
}, 100);
}
foo(2, 4, 6, 8)
// Array: [2, 4, 6, 8]
总结
普通函数
- 方法调用中, this 指向调用它所在方法的对象。
- 单独使用 this,它指向全局(Global)对象,默认指向window。
- 严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
- apply、 call 、bind允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
- 构造函数中this指向new出来的对象。
箭头函数
- this指向定义它的对象。