一、普通函数this指向 :
普通函数this指向函数最终被调用的对象;
注意:普通函数在 "use strict" 严格模式下,this不再指向window;
/*非严格模式下:*/
function fn(){
console.log(this);
}
fn();//window 说明:当前调用相当于window.fn();调用,故this指向window
var fn = function(){
console.log(this);
}
fn();//window 说明:当前调用相当于window.fn();调用,故this指向window
var obj = {
a: 1,
b: {
a: 2,
fn: function(){
console.log(this.a,this.b);
}
},
fn1: function(){
console.log(this.a);
}
}
obj.fn1(); //1 说明:this指向obj,当前函数被obj调用,故this指向obj
obj.b.fn(); //2,undefined 说明:指向obj.b,尽管对象被函数是被最外层的obj所调用,this指向的也只是它上一级的对象
var j = obj.b.fn;
j(); //undefined,undefined 说明:this指向windows,this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的
二、箭头函数this指向:
捕获其所在(即定义的位置)上下文的this值,一直向上查询上下文的this值,无论是否严格模式; 注意:call(),apply(),bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响;
var fn = () => {
console.log(this);
}
fn(); //window 说明:获取上下文的this值
var obj = {
fn: () => {
console.log(this);
(() => {
console.log(this);
})();//window 说明:获取一直向上查询上下文的this值
}
}
obj.fn(); //window 说明:获取上下文的this值
var obj = {
say: function () {
var fn = () => {
console.log(this);
};
setTimeout(fn, 1000);
}
};
obj.say(); //say 说明:获取上下文的this值
function Person() {
setInterval(() => {
console.log(this); //Person 说明:获取上下文的this值
}, 3000);
setTimeout(((arg) => {
console.log(this, arg); //Person 100 说明:箭头函数绑定this没有作用this仍为Person,传参成功
}).bind(undefined, 100), 3000);
}
var p = new Person();
三、构造函数this指向:
构造函数相当于复制了一份新的对象,this与被创建的新对象绑定。
this遇到return:
如果返回值是 原始值,那么this指向函数的实例,否则为 undefined;
function fn(){
this.user = '二狗子';
return {};
//return function(){};
//return [];
//return new Date();
//return new Number();
}
var a = new fn();
console.log(a.user); //undefined 说明:this没有指向
function fn(){
this.user = '二狗子';
return null;
//return undefined;
//return "";
//return 0;
//return true;
//return Symbol('a');
}
var a = new fn();
console.log(a.user); //二狗子 说明:this指向函数实例
四、DOM事件(函数非箭头函数):
this指向触发事件的元素
五、内联事件中的this指向:
onclick="console.log(this);" //DOM元素 说明:当代码被内联处理函数调用时,它的this指向监听器所在的DOM元素
onclick="function()(console.log(this);)();" //window
onclick="function()('use strict';console.log(this);)();" //undefined
六、延迟器的this指向:
var obj = {
abc: function(){
setTimeout(()=>{
console.log(this); //obj 说明:箭头函数,捕获其所在(即定义的位置)执行上下文的this值
}, 2000);
setTimeout(function() {
console.log(this); //window 说明:无论在哪setTimeout里function的this是window
}, 3000);
setTimeout((function() {
console.log(this); //obj 说明:经过bind绑定
}).bind(this), 3000);
}
}
七、绑定this(修改this指向):
function Person() {
this.age = 10;
setTimeout((function() {
console.log(this.age); //10 说明:绑定this为Person
}).bind(this), 3000);
setTimeout((function() {
console.log(this.age); //undefined 说明:绑定this为undefined
}).bind(undefined), 3000);
setTimeout(() => {
console.log(this.age); //10 说明:箭头函数的this向上查找上下文的this值为Person
}, 3000);
setTimeout(((age) => {
this.age = age;
console.log(this.age); //27 说明:箭头函数绑定this没有作用this仍为Person,传递参数成功
}).bind(undefined, 27), 3000);
}
var p = new Person();
this绑定方法说明:
.call(对象, 参数1, ...,参数n);
.apply(对象, [参数1, ...,参数n]);
.bind(对象, 参数1, ...,参数n)();
说明:
三种方法的第一个参数都指定函数内部中this的指向函数执行时所在的作用域,
都可以在函数调用时传递参数:call,bind方法需要直接传入,而apply方法需要以数组的形式传入。
call,apply方法是在调用之后立即执行函数,而bind方法没有立即执行,需要将函数再执行一遍。
八、总结:
- 通常this指向执行被调用的对象;
- 如果函数return的对象为原始值,那么this指向函数的实例,否则为undefined;
- 构造函数相当于复制了一份新的对象,this与被创建的新对象绑定;