一:全局中执行
浏览器环境————————window
node————————global
sdsd
二:严格模式 ‘use strict’
'use strict';
function test() {
console.log(this);
}
test()//undefined
等同于====
(function (){
"use strict";
console.log(this);
})();
二:作为对象方式调用
第一种情况 作为对象方式调用且 执行
var obj={
name:"111",
show:function(){
console.log(this,this.name)
}
}
obj.show()//obj,111
等同于=====
function show(){
console.log(this,this.name)
}
var obj={
name:"11",
show:show
}
obj.show()
第二种情况 作为对象方式调用且 没有执行
var name="quanju"
var obj={
name:"jubu",
test:function(){
console.log(this,this.name)
}
}
var test=obj.test;//虽然引用了obj对象中的函数 ,但是没有执行,
相当于是吧这个函数引用地址给了变量test,再执行test的时候,是相当于window.test();
test()//window,'quanju'
三:作为一个构造函数使用(new)
function Person(name){
this.name=name;
console.log(this)
}
var person =new Person("冯思颖");//this指向person,new之后被引用的变量
四:箭头函数的this
简单来说, 箭头函数中的 this 只和定义它时候的作用域(外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window)的 this 有关而与在哪里以及如何调用它无关,同时它的 this 指向是不可改变的,包括 (call, apply, bind) 等操作都无法改变它的 this。
箭头函数没有⾃⼰的this,需要看其外层的是否有函数,
var obj={
foo1:function(){
console.log(this)
},
foo2:() => {
console.log(this)
},
foo3:function(){
(()=>{console.log(this)})()
}
}
obj.foo1()//obj
obj.foo2()//window
obj.foo3()//obj,在foo3内部的箭头函数定义时,它的this就指向了foo3的this。
四:call, apply, bind重定向this
call传入的参数是call(this对象,参数1,参数2);立即执行
apply(this对象,[参数1,参数2,参数3]),立即执行
bind绑定的返回的是一个新的函数,不会立即执行,bind的优先级比call和apply都要高
var obj={
name:"11",
age:0,
}
var obj2={
name2:"222",
age:0,
test:function(age){
this.age=age
console.log(this,age)
}
}
obj2.test(23)//obj2,25
obj2.test.call(obj,"25")//obj,25
obj2.test.apply(obj,[25])//obj,25
var bindObj=obj2.test.bind(obj,25)
bindObj();//obj,25
var newTest=new obj2.test.bind(obj,25)//this没有改变,但是能接收到25这个参数
这里使用call和apply会报错,因为new obj2.test.call(obj.25)这里的call的优先级跟一般函数一样,这里的执行顺序会按照点函数从左到右执行,就会变成obj2.test.call。这里的obj2.test.call
并不是一个函数,就会报错。
使用bind时,bind的优先级会高于new,就会先执行obj2.test.bind(obj,25),再执行new。但是这里的this并没有改变。
结论:在 new 这个构造函数的时候,bind 函数所指定的 this 并不会生效;
采坑点:遇到定时器时的this指向
第一种情况:定时器传入的函数是一般的函数时
var name="quanju"
var obj={
name:"jubu",
foo:function(){
console.log(this,this.name)
},
foo1:function(){
console.log(this)//obj
setTimeout(this.foo, 1000);
}
}
obj.foo1();//foo的输出是window,foo1输出的是obj。
坑1:在调用obj.foo1中的setTimeout(this.foo, 1000)中,这里的this.foo也是直接
拿到的是 foo函数的引用地址,并没有执行,相当于这里放传入的只是一个普通的函数。
坑2:setTimeout的特性是,即使在严格模式下,setTimeout 方法在调用传入函数的时候,
如果这个函数没有指定了的 this,那么它会做一个隐式的操作—-自动地注入全局上下文,
等同于调用 foo.apply(window)。也就是说ding
解决:重定向this,在setTimeout调用时外面用var _this=this;在定时器内部使用_this;
第二种情况:定时器传入的函数是一般的函数时
var obj={
name:"jubu",
foo:function(){
console.log(this,this.name)
},
foo1:function(){
console.log(this)//obj
setTimeout(()=>{
console.log(this)//这里的this等同于foo1的this
}, 1000);
}
}
obj.foo()//obj,jubu
obj.foo1()//obj