什么是this
this是JavaScript中定义的一个关键字,是指向调用该this的对象的。
this本身也是一个对象,可以在函数执行时保存该函数里相关的值;其存在的目的是利用this指向的不同可在不同的对象环境中执行这个函数,达到复用的效果。
this是在函数执行时浏览器自动为函数定义的一个对象,在默认情况下指代的是window。在严格模式下,this指向的是null。
不同情况下的this
-
普通函数:谁调用this指向谁
var a = 1; var fn1 = function (){ console.log(this.a) } var obj = { a: 2, fn2: fn1 } fn1() // 输出 1 obj.fn2() // 输出 2
执行 fn1 函数的时候,this指向window 所以输出 a 的值为 1。指向 obj.fn2 函数的时候,this指向obj 所以输出 a 的值为 2
-
构造函数:this指向被创建的新对象
function Person(name,age){ this.name = name; this.age = age; this.sayname = function(){ console.log(this.name); }; } var p1 = new Person('tom',10); console.log(p1.name) // 输出结果为tom console.log(p1.age) // 输出结果为10 console.log(p1.sayname()) // 输出结果为tom
用new操作符调用的一个函数。用new时构造函数内部的this会指向新的实例。所以可以 正常输出值,倘若不同过new操作符声明,则this指向window,输出报错
-
dom事件:指向触发函数的dom元素
let btn = document.getElementById('btn'); btn.onClick(function (){ console.log(this) })
该情况下输出this指向即为id为btn的Dom元素信息
-
setTimeout和setInterve中的this指向全局
var num = 0; function Obj (){ this.num = 1, this.getNum = function(){ console.log(this.num); }, this.getNumLater = function(){ setTimeout(function(){ console.log(this.num); }, 1000) } } var obj = new Obj; obj.getNum(); //1 打印的是obj.num,值为1 obj.getNumLater() //0 打印的是window.num,值为0
setTimeout中函数内的this是指向了window对象,这是由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象。
若想解决setTimeout和setInterve的this指向可通过以下方法- 用变量保存this
var that = this; setTimeout(function(){ console.log(that.num); }, 1000)
- 使用bind()方法
setTimeout(function(){ console.log(this.num); }.bind(this), 1000)
- 通过箭头函数
setTimeout(() => { console.log(this.num); }, 1000)
- 用变量保存this
-
call()和apply():this指向第一个参数
var a ="windowA"; var b = "windowB"; var str = "str"; var myObject = {a:"myA",b:"myB"}; function hello(s){ alert("a= "+this.a + ", b= "+this.b+" "+s); } hello.call(null,str);//a ="windowA" b = "windowB" str hello.call(window,str); //a ="windowA" b = "windowB" str // 如果第一个参数为null,则this指向window(在node环境中则指向global) hello.call(myObject,str);//a="myA" b="myB" str
-
箭头函数:最初创建函数时的作用域
var obj={ fn:function(){ console.log(this); } } obj.fn();//object
箭头函数本身是不存在this,它的this绑定看的是this所在的函数定义在哪个对象下,绑定到哪个对象则this就指向哪个对象。如果有对象嵌套的情况,则this绑定到最近的一层对象上