普通函数中的this指向问题
普通函数的this指向如果用一句话概括的讲,是最后调用它的对象,下面分情况来看
1.该函数没有被上一级调用,那么this指向window
var name = 'mt'
function mt (){
var name = 'ff'
console.log(this.name);//mt
}
mt()
这里的mt函数没有被上一级调用,所以它的this指向最后的调用的对象——全局window
var mt = 'mt'
var obj = {
mt: 'ff',
a:{
getmt:function(){
console.log(this.mt);//mt
}
}
}
var test = obj.a.getmt
test()
这里的最后调用者是window,因为test被赋值时,并未执行函数,而执行test时,是和上一种情况一致的,所以输出window的mt,即mt
2.该函数被上一级对象调用,那么this指向上一级对象(多层调用时也是指向上一级对象)
var name = 'mt'
var obj = {
fn:function mt (){
var name = 'ff'
console.log(this.name); //aa
},
name:'aa'
}
obj.fn()
这里fn被obj调用,所以this指向最后的调用对象——obj
var name = 'mt'
var obj = {
fn:{
mt:function mt (){
var name = 'ff'
console.log(this.name); //bb
},
name:'bb'
},
name:'aa'
}
obj.fn.mt()
这里对象obj调用对象fn,对象fn调用mt方法,所以this指向上一层对象,即最后的调用对象fn
3.当函数作为构造函数,return相关的情况
(1)函数return的是对象或方法,
function mt(){
this.name = 'mt'
return {}
}
function mt2(){
this.name = 'mt'
return function(){
this.name = 'aa'
}
}
var a = new mt
var b = new mt2
console.log(a.name);//undefined
console.log(b.name);//“”
这里的 a是mt方法return的空对象{},没有属性name,所以为undefined
而b是mt方法return的方法,该方法的name为空(匿名函数),所以为空
(2)函数return number/string/undefined/null
function renum(){
this.name = 'mt'
return 1
}
function restring(){
this.name = 'mt'
return '1'
}
function reun(){
this.name = 'mt'
return undefined //等于没写 等于 return
}
function renull(){
this.name = 'mt'
return null
}
var a = new renum
var b = new restring
var c = new reun
var d = new renull
console.log(a.name); //mt
console.log(b.name); //mt
console.log(c.name); //mt
console.log(d.name); //mt
这里this指向函数的实例,所以都是输出mt,这里null比较特殊,因为它是对象,但属于这种情况,需要注意
扩展—— 函数提升、执行语句优先级、this指向
var getName = function () {
console.log(4)
}
function Foo () {
getName = function (){
console.log(1)
}
return this
}
Foo.getName = function () {
console.log(2)
}
Foo.prototype.getName = function () {
console.log(3)
}
function getName(){
console.log(5)
}
Foo.getName() //2
getName() // 4
Foo().getName() //1
getName()//1
new Foo.getName()//2
new Foo().getName()//3
new new Foo().getName() //3
箭头函数中this指向问题
箭头函数的this指向如果用一句话概括的讲,是定义该函数时,上下文环境的this,它没有自己的this,都是copy所处作用域的this的
1.this指向在定义时就已经确定,是静态的,且不会被bind,call,apply修改
const test1 = () => {
console.log(this);
}
test1()
test1定义时所处的作用域为全局,所以输出window
let obj = {
user:'mt',
test:function(){
console.log(this.user); //mt
const test1 = () => {
console.log(this.user);//mt
}
test1()
}
}
obj.test()
test1定义时,this指向test1所处作用域的this,即function(){}中的this
而test的最后调用者是obj,所以this指向obj
var obj = {
say: function () {
console.log(this) //obj
var f1 = () => {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
})
}
f1();
}
}
obj.say()
无论嵌套多少层,箭头函数的this都和上一层作用域的this保持一致
综合题汇总
var obj = {
x:100,
show(){
console.log(this.x);//100
setTimeout(
//普通函数
function(){console.log(this.x);}//undefined
,0
);
},
show2(){
console.log(this.x);//100
setTimeout(
//箭头函数
()=>{console.log(this.x);}//100
,0
);
}
};
obj.show()
obj.show2();
调用show()时,执行到settimeout方法时,调用对象即最后调用对象成了全局,所以输出this为window