this指向问题
一、this是什么?
- this是JavaScript中定义的一个关键字,是指向调用该this的对象的,简单来说this 就是你调用 一个函数时,传入的 context(当前调用函数的环境对象),this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
- this永远指向一个对象;
- this的指向完全取决于函数调用的位置
二、示例
- 哪个对象调用方法,this就指向哪个对象
var o = { a:10, b:{ a:12, fn:function(){ console.log(this.a); //12 } } } o.b.fn(); //fn方法最终是由b调用的,所以当前的this指向b,所以打印的a值为b作用域的值 - 直接调用的函数,this 指向的是全局 window 对象
function a(){ var user = "abc"; console.log(this.user); //undefined console.log(this); //Window } a(); //等价于 window.a(), 所以this指向的是window - 构造函数的this
function Fn(){ this.user = "111"; } var a = new Fn(); console.log(a.user); //构造函数里this指向的是指向生成的对象实例,所以打印结果为111 - 其他场景
//严格模式的this function demo() { 'use strict'; alert(this); // undefined } demo();//严格模式下 this指向undefined //定时器中的this setTimeout(function() { alert(this); // this -> 指向window },500)
四、如何改变this指向
- 箭头函数
- 不管在什么情况下,箭头函数的this跟外层function的this一致,外层function的this指向谁,箭头函数的this就指向谁,如果外层不是function则指向window
//这里是外部作用域 this指向window,即最终console中的this指向window let person1 = { name:'lisi', age:10, say:()=>{ //这里是外部作用域,因为本身又是箭头函数,继续向上找 setTimeout(() => { console.log(this); //this指向外部作用域中this }); } } person1.say(); //输出window let obj1 = { name:'111', foo: function() { setTimeout(()=>{ console.log(this); // obj2 }, 1000); }, } obj1.foo();// obj1
-
call 修改this指向
function a(){ console.log('name:'+this.name) // name:obj1 console.log(arguments) } var obj1 = { name:'obj1' } a.call(obj1,1,2,3) //this指向为obj1对象 -
apply修改this指向
function b(){ console.log('name:'+this.name) // name:obj2 console.log(arguments) } var obj2 = { name:'obj2' } b.apply(obj2,[1,2,3]) //this指向为obj2对象 -
bind修改this指向
function c(){ console.log('name:'+this.name) // name:obj3 console.log(arguments) } var obj3 = { name:'obj3' } c.bind(obj3,[1,2,3])() //this指向为obj3对象call 、bind 、 apply 区别: 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别为call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 fun.call(this,'1','2','3' )。 apply 的所有参数都必须放在一个数组里面传进去 fun.apply(this,[1,2,3])。 bind 除了返回是函数以外fun.apply(this,[1,2,3])(),它 的参数和 call 一样。