一文彻底搞懂普通函数和箭头函数this指向区别

普通函数和箭头函数

注:例子建立在非严格模式下,新版chrome浏览器下

严格模式下:window是undefined

node下:window是global

网上有很多理解,这里写下我的理解法

最大的区别:

普通函数:this指向它的上级宿主对象(没有就指向window)

箭头函数:本身没有this,是从直接调用者(主要是向上找上级函数作用域)上面继承下来的,如果没有,就指向全局作用域window

举几个例子

//sayA函数没有宿主对象,this就是指向window,window.name = undefined
const sayA = function(){
    const name = 'hc';
    console.log(this.name+' say');
}
sayA();//undefined say 等价于window.sayA();

//没有sayB的直接调用者,就是指向window
const sayB = () => {
    const name = 'hc';
    console.log(this.name+' say');
}
sayB();//undefined say

const objA = {
	name : 'hc',
	say: function() {
		console.log(this.name+' say'); 
	}
}
//say的宿主对象是objA,所以this指向obj
objA.say();//hc say

const objB = {
	name : 'hc',
	say: () => {
		console.log(this.name+' say'); 
	}
}
//没有say的直接调用者(注意这里的objB不属于它的直接调用者),所以指向window
objB.say();//undefined say

//还有一种写法是这样的,和objA和objB其实是一样的
const obj = {
    name: 'hc'
}
const fnSay = function(){
    console.log(this.name+' say');
}
const fnSay = () => {
    console.log(this.name+' say');
} 
fnSay.call(obj);//等价于objA,objB的结果


const objC = {
    name: 'hc',
    say: function(){
		console.log(this.name+' say');
        return function(){
            console.log(this.name+' repeat');
        }
    }
}

//say函数的宿主对象是objC,所以this = objC,
//say底下的function上级宿主对象没有,所以this = window
objC.say()();
//hc say
//undefined repeat

const objD = {
    name: 'hc',
    say: function(){
		console.log(this.name+' say');
        return () => {
            console.log(this.name+' repeat');
        }
    }
}

//say函数的宿主对象是objC,所以this = objC,底下的()=>,
//向上找函数作用域,是say function所在的作用域,所以直接调用者是objC
objD.say()();
//hc say
//hc repeat

window.a = 'daxian';

const objE = {
    a: 'hc',
    run: function(){
    	return {
            b: this.a + ' run',
            runDown: () => {
                console.log(this.a+ ' runDown');
                console.log(this.b+ ' runDown');
                return function(){
                    console.log(this.a+ ' runDeep');
                    console.log(this.b+ ' runDeep');
                }
            }
        }
	},
    walk: () => {
        return {
            b: this.a+ ' walk',
            walkSlow: function() {
                console.log(this.a+ ' walkSlow');
                console.log(this.b+ ' walkSlow');
            },
            walkFast: () => {
                console.log(this.a+ ' walkFast');
                console.log(this.b+ ' walkFast');
            }
        }
    }
}

objE.run().runDown()();
objE.walk().walkSlow();
objE.walk().walkFast();
// hc runDown
// undefined runDown
// daxian runDeep
// undefined runDeep
// undefined walkSlow
// daxian walk walkSlow
// daxian walkFast
// undefined walkFast

objE的例子分解一下

objectE.run().runDown()();

  • .run()普通函数:上级宿主对象的是objectE,所以返回一个新对象时候,b属性的this.a是指objectE底下的a,为’hc’,所以此时的b为this.a+’ run’为’hc run’
  • .runDown()箭头函数:向上找函数作用域,它的上级函数作用域是run函数,所以对应的直接调用者是objectE,所以此时的this.a为 ‘hc’,objectE底下的b属性没定义,所以this.b为undefined。
  • runDown底下的()普通函数:上级宿主对象没有,所以this指向window,window的a属性为’daxian’,b属性没定义,所以this.a = ‘daxian’,this.b=undefined

objectE.walk().walkSlow();

  • .walk()箭头函数:向上找函数作用域,没有,则直接调用者是window,返回一个新对象的时候,b属性的this.a为window.a,this.a+‘ work’为’daxian work’
  • .walkSlow()普通函数:上级宿主对象为.walk()返回的那个对象,所以this.a为undefined,this.b为’daxian work’。

objectE.walk().walkFast();

  • .walk()箭头函数:原理已写。
  • .walkFast()箭头函数:向上找函数作用域,没有,则直接调用者是window,因为window.a=‘daxian’,所以this.a+‘ walkFast’为’daxian walkFast’,window.b没定义为undefined,this.b+’ walkFast’为’undefined walkFast’

下一章
普通函数this指向进阶实例讲解

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值