指向调用函数的那个对象,是函数运行时内部自动生成的一个内部对象,只能在函数内部使用
使用场景
-
单纯的函数调用this的值为window,默认绑定全局变量(符合一句话)
function f(){ this.x=1; // this.x改变的是全局的x. console.log(this.x); console.log(x) //x也是可以正常输出的,注意之前是没有定义过x的,那就相当于*this.x*还会定义和修改this所指的变量 } console.log(x) //同理,此处也是可以正常显示x的
-
this作为对象的一个方法调用,这时的this就指这个上级对象,函数拥有了一个上下文,此时这个函数属于这个对象,而且调用了他。
不符合的情景有以下几种:情景1:对象调用了全局函数,全局函数会一直挂载到window对象下面(setInterval,setTimeout..)所以this会指向window,解决这个问题要和后面的箭头函数this一起谈。匿名函数因为没有默认的宿主对象,所以默认指向window,可以说匿名函数的执行具有全局性。自执行函数的this也是指向window(注意严格模式下不是window,失效) var a=100 function h(){ var a=1; function ok22(){ console.log(this.a) console.log(a) } ok22(); // this总是指向调用他的对象为什么这个ok函数的调用者是window。ok22是一个自执行,他是在h的作用域之中调用了此时函数是没有调用者的,所以this指向window.虽然他是在函数内部定义的,但是他任然属于一个普通函数,所以this指向window. } h(); 情景2:对象函数的使用问题 var x=10; var obj={ x:1, y:2, z:'', toX(){ console.log(this.x) setTimeout(function(){ console.log(x); },10) } toZ(){ console.log(z); } } var ok=obj.toX; //这样调用的时候取不到我们想要的x,因为此时ok函数早以变成了全局函数,所以此时两个值输出都为10 obj.toX() //这样才会得到我们想取的x,但是setTimeout调用的还是全局的x,证实了我们上边的结论。
this作为构造函数,this指向新对象,可以使用this得到构造时候的值,和一同构造的方法。
-
apply调用,改变函数的调用对象,第一个参数就是表示改变之后的调用这个函数的对象,也就是this的指向(一句话:就是把一个函数塞到一个对象里面,让他把这个对象当成新的家,可以让this有新的绑定,达到某种不可告人的目的)
var obj={
a:2
}function f(){ console.log(this.a); } f.call(obj); 输出2 var a='outer' f.call(null) 输出undefined
DOM event this:this始终指向这个处理程序所绑定的HTML DOM节点,相当于currentTarget.
箭头函数的情况:箭头内部的this是词法作用域,由上下文确定。他的this只和定义它的作用域有关,而与在哪里以及如何调用他无关,同时他的指向是不可变的
同时使用优先级比较 new >显式绑定>隐式绑定
-
当this在函数里面碰到return时,如果返回值是一个对象,那么this指向那个返回的对象,如果返回值不是一个对象,那么this指向函数的实例。
自测题目 var sex = "male"; var saySex = { sex:"female", saySex:function(){ function getSex(){ console.log("this.sex="+this.sex); } getSex(); } } saySex.saySex(); //this.sex =male var ccc = saySex.saySex; ccc();//this.sex = male var a = { name:"zhang", sayName:function(){ console.log("this.name="+this.name); } }; var name = "ling"; function sayName(){ var sss = a.sayName; sss(); //this.name = ling a.sayName(); //this.name = zhang (a.sayName)(); //this.name = zhang (b = a.sayName)();//this.name = ling(和表达式会返回一个值有关) } sayName(); var sex = "male"; var saySex = { sex:"female", saySex:function(){ function getSex(){ console.log("this.sex="+this.sex); } getSex.call(this); //与例2只有这个地方的变化 } } saySex.saySex(); //this.sex = female var ccc = saySex.saySex; ccc();//this.sex = male var name = "ling"; function sayName(){ var a = { name:"zhang", sayName:getName }; function getName(){ console.log(this.name); } getName(); //this.name = ling a.sayName(); //this.name = zhang getName.call(a);//this.name = zhang } sayName(); var name = "ling"; var obj = { name:"zhang", sayName:function(){ console.log("this.name="+this.name); }, callback:function(){ var that = this; return function(){ var sayName = that.sayName; that.sayName(); //this.name = zhang sayName();//this.name = ling } } } function addEvent(obj,type,callback){ if(obj.addEventListener){ obj.addEventListener(type,callback,false); }else if(obj.attachEvent){ obj.attachEvent("on"+type,callback); }else{ var fn = obj["on"+type]; obj["on"+type] = function(){ fn && fn(); callback(); } } } addEvent(document,"click",obj.callback()); window.val = 1; var obj = { val: 2, dbl: function () { this.val *= 2; val *= 2; // 这个值会影响后面的计算,全局变量一不小心被改变 console.log(val); console.log(this.val); } }; // 说出下面的输出结果 obj.dbl(); console.log(val) var func = obj.dbl; func();