彻底搞懂浏览器和node.js中的this指向问题!

彻底搞懂JavaScript中的this指向问题!

之前遇到this指向问题总是一知半解,今天花了一些时间深入了解了一下,接下来我会把我的理解通俗易懂的讲出来,希望以后大家都能明白this指向。

首先搞明白this的定义:this为代码运行时所处的环境!本质上所有的函数都是通过对象调用,所以最终是谁调用的函数,函数内部的this就是谁。

this在浏览器中的指向

node.js中大部分的指向和普通运行环境一致,所以此处先说明大部分情况,最后node.js差异部分单独说明。

1.普通函数的this指向他的调用者

	let name='window'
	let obj={
		name:'obj'
		getName:function()
		{
			console.log('getName:',this.name)
		}
	}
	obj.getName()	//getName:obj

2.箭头函数的this:箭头函数没有自己的this,所以指向定义时所在环境

	var name='window'
	let obj={
    	name:'obj',
    	getName:()=>
    	{
        	console.log('getName:',this.name)
    	}
	}
	obj.getName()		//getName:window

可以看到此处getName声明为箭头函数,函数体中的this定义时的调用者环境,即obj所处环境的this(window对象),可以简单理解为:对比普通函数来说,箭头函数指向他外层的this(普通函数的this的外一层this)。
3.定时任务,setTimeout,无论是否为箭头函数,this都指向的是window,因为定时任务是浏览器调用的,所以指向最顶层的window对象。

	let name='window'
	setTimeout(function() {  
    	console.log('getName:',this.name)	//getName:window
	}, 200);
	let name='window'
	setTimeout(()=> {  
    	console.log('getName:',this.name)	//getName:window
	}, 200);

4.构造函数的this指向他的构造对象

	function user()
	{
    	this.name='name'
    	this.id=00000000
	}
	let lucy=new user();
	console.log('name:',this)				//name: user {name: 'name', id: 00000000}

值得注意的一点是:如果构造函数返回体中return非对象类型,则构造函数创建的实例对象不变,否则会发生改变

	function user()
	{
    	this.name='name'
    	this.id=00000000
	    return 1
	}
	let lucy=new user();
	console.log('name:',lucy)				//name: user {name: 'name', id: 00000000}
	function user()
	{
    	this.name='name'
    	this.id=00000000
	    return {}
	}
	let lucy=new user();
	console.log('name:',lucy)				//name: {}

this在node.js中的指向

我们知道,在node.js中全局对象为global对象,所以我们理所当然的认为node只是把浏览器中的全局对象windows替换成了global对象,所以我们运行以下代码

	global.name = 'node.js'
	function getName(){
    	console.log(this.name); 			//输出“node.js”
	}
	getName()
结果确实如我们所料,跟windows中的预期一样,但是真的是看起来这么简单吗?

但是答案是:node.js中其实不是单单把windows替换成global这么简单。
如果我们运行如下代码会发现:

	console.log(this); 						//输出 {}
	this.name = 'test' 
	console.log(this === global); 			//输出 false
	function test(){
    	console.log(this === global); 		//输出 true
    	console.log(this.name); 			//输出 undefined
	}
	test();

在本来应该相等的第三行却不相等,第六行也没有得到我们想要的name字段!
也就是说,最外层的this不等于global,但是test函数的this指向了global,所以结论是第二行的this也就是最外层的this并不指向global,而是指向了{}这个对象。
所以我们得到最终的结论:
1.Node在执行js文件中的代码的时候,并不是放在全局环境中执行的。而是把js文件外面又包了一层成“模块”(module.exports),再把这个“模块”放到了全局变量中执行。所以,最外层的this,指的是包含这个js文件的“模块”。
2.Node中的全局对象是global,但是不在最外层,当调用函数时,函数中的this指向的是global。
3.如果想获取全局变量中的this,可以使用globalThis属性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值