1.this的概述
1 this指向的是一个对象,函数执行的上下文对象;
2 在这里我把this理解为一个操作这个函数执行的句柄(操作者),就像一个人(this)拿着锯子(函数)去锯木头(函数执行的上下文对象功能);
-
全局环境中this指向全局变量(window);
-
函数中的this,由调用函数的方式来决定,
(1)如果函数是独立调用的,在严格模式下(use strict)是指向undefined的,在非严格模式下,指向window;
(2)如果这个函数是被某一个对象调用,那么this指向被调用的对象;
-
构造函数与原型里面的this
构造函数里的this以及原型里的this对象指的都是生成的实例;(由new决定的)
通过new操作符可以初始化一个constructor的指向,new的作用就是创建一个对象的实例,constructor也就指向了一个新的执行环境“在这个对象之中”;
- 箭头函数按词法作用域来绑定它的上下文,所以this 实际上会引用到原来的上下文。
(箭头函数会保持它当前执行上下文的词法作用域不变,而普通函数则不会,箭头函数从包含它的词法作用域中继承了this的值)
(3) 根据函数的调用方式的不同,this会指向不同的对象
2 普通函数中的this指向
当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象
//普通函数
function f1() {
console.log(this);
}
f1() //这里this会指向window,默认指向为window
3 定时器的this的指向
setInterval(function () {
console.log(this);
},2000);//同理这里this也会指向window
4 对象中方法的this的指向
function Person() {
console.log(this);
this.sayHi = function () {
console.log(this);
}
}
var per = new Person();//对象中方法的this指向实例对象
per.sayHi();
5 原型对象方法的this的指向
function Person() {}
Person.prototype.sayHi = function () {
console.log(this);
};
var per = new Person();
per.sayHi();//this会指向Person,原型对象方法中的this指向实例对象
6 箭头函数的this指向
var obj = {
a: function () {
setTimeout(() => {
console.log(this);//this是箭头函数外this的指向,在这里是a
// 上下文环境中this的指向
}, 2000);
},
};
obj.a();
var obj={
a:function(){
document.addEventListener("click",this.clicHandler);
},
clicHandler:function(e){
setTimeout(()=>{
console.log(this);
},2000);
}
}
obj.a();//#document
7call apply bind的this指向
fn.call(obj);//fn中this指向obj
fn.apply(obj);//fn中this 指向obj
fn.bind(obj)();//fn中this指向obj
var obj={
a:function(){
function fn(){
console.log(this);
}
fn();
console.log(this);//window 如果是call apply bind 带入的是null,将会把这里的this重新指向window
}
}
obj.a();//window
obj.a.call(null);//window
8 ES6中this指向
// ES6类
class Box{
static _instance;
constructor(){
console.log(this);//指向被实例化的对象
}
static getInstance(){
if(!Box._instance){
Box._instance=new Box();
}
return Box._instance;
}
play(){
console.log(this,"|");//指向被实例化的对象
}
static run(){
console.log(this);
console.log(this===Box,"____");
// this就是当前类名也是构造函数
// 任何的静态方法中this都是当前类
// 静态方法中无法获取到实例化对象的this的
return this;
}
var b=new Box();//会执行构造函数,这是构造函数中this就是这个b对象
b.play();//b对象下的方法play,因此play方法中this被指向b,谁执行play,this指向谁