关于普通函数和箭头函数中的this指向问题

本文详细探讨了JavaScript中普通函数和箭头函数的this指向问题。在普通函数中,this取决于函数的调用方式,包括全局环境、对象调用以及构造函数返回情况。而在箭头函数中,this是在定义时确定的,始终指向所在作用域的this,不受bind、call、apply影响。文章通过实例解析了各种情况下的this指向,帮助读者深入理解这一关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普通函数中的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值