JavaScript中this的指向问题

函数 与 this

this 是一个特殊的对象,它在标准函数和箭头函数中有不同的行为。

在标准函数中,this引用的是把函数当成方法调用的上下文对象,这时候通常称其为this值(在网页的全局上下文中调用函数时,this指向Windows)。

			window.color = 'red';
			let obj = {
				color : 'blue'
			}
			function sayColor(){
				console.log(this.color)
			}
			sayColor();
			obj.sayColor = sayColor;
			obj.sayColor();

定义在全局上下文中的函数sayColor()引用了this 对象。这个 this 到底引用哪个对象必须到函数被调用时才能确定。因此这个值在代码执行过程中可能会发生改变。如果在全局上下文中调用sayColor() ,这个结果会输出“red”,因为此时 this 指向 window,而this.color 相当于window.color。后面把sayColor赋值给 obj对象之后再去调用obj.sayColor,此时的this 指向obj对象,故而this.color相当于obj.color,所以显示“blue”。

在箭头函数中,this的引用是定义箭头函数的上下文。下面的例子演示了这一点。在对sayColor()的两次调用当中,this的引用的都是window对象,因为这个箭头函数都是在window的上下文中定义的:

    window.color = 'red';
    let o = {
      color: 'blue',
    }
    let sayColor = () => console.log(this.color);
    sayColor();//red。这时候的this指向的是sayColor的上下文即: window对象
    o.sayColor = sayColor;
    o.sayColor();//red。同样指向的是 对象的上下文也是window对象

这里我们知道,在事件回调或者定时回调中调用某个函数时,this值的指向的并非都是想要的对象。此时将回调函数写成箭头函数就可以解决问题,这是因为箭头函数中的this会保留定义该函数的上下文

如果内部函数中没有使用箭头函数定义,则this对象会在运行时绑定到执行函数的上下文。

	function getIdentityFunc(){
					identity = 'My Object';
					return function(){
						return this.identity;//这个this是执行函数,也就是说他绑定的上下文是 getIdentityFunc
					}
				}
console.log(getIdentityFunc()())//My Object

如果在全局函数中调用,则this在非严格模式下等于 window,在严格模式下等于 undefined。,

如果作为某个对象的方法调用,则this等于这个对象匿名函数在这种情况下不会绑定到某个对象,这意味着this 会指向 window对象,除非在严格模式下this 是 undefined。

window.identity = 'The window';

			let object = {
				identity : 'My Object',
				getIdentityFunc(){
					return function(){
						return this.identity;
					}
				}
			}
			
console.log(object.getIdentityFunc()());//The window

这里先创建了一个全局变量 identity ,之后又创建一个包含 identity 属性对象。这个对象还包含一个getIdentityFunc()方法,返回一个匿名函数。这个匿名函数。这个匿名函数返回this.identity。因为getIdentityFunc()返回函数,所以 object.getIdentityFunc() ()会立即调用这个返回的函数,从而得到一个字符串。科了,,室,此时返回的字符串是“The window”,即:全局变量 identity 在值。为什么匿名函数没有使用其包含的作用域【getIdentityFunc()】的this对象?

由于每个函数在被调用时都会自动创建两个特殊变量:this 和 argument。内部函数蝾螈不可能直接访问外部外部函数的两个变量。但是,如果把 this 保存到闭包可以访问的另一个变量中,则是行的通的

			window.identity = 'the window';
			let object = {
				identity : 'My Object',
				getIdentityFunc(){
					let that = this;
					return function(){
						return that.identity;
					}
				}
			}
console.log(object.getIdentityFunc()());//My Object

在这个例子上,在定义匿名函数之前,先把外部函数的this保存在变量 that 中。然后在定义闭包时,就可以让它访问 that ,因为这是包含函数中名称没有任何冲突的一个变量。即使在外部函数返回之后,that仍然指向Object,所以调用object.getIdentityFunc()就会返回“My Object”。

但是在一些特殊的情况下,this的值可能并不是我们所期待的值。比如

    window.identity = "My Windows";
    let Object = {
      identity: "My Object",
      getImdentity(){
        return this.identity
      }
    }
  

console.log(Object.getImdentity()) 输出的是“My Object”

但是Object.getImdentity()的调用方式不同,其最后的结果也会出现不同。

console.log(Object.getImdentity());
console.log((Object.getImdentity)());
console.log((Object.getImdentity=Object.getImdentity)());
结果:
My Object
My Object
My Windows

第一行的输出是正常调用Object.getImdentity(),会返回“My Object”,因为this.identity就是 Object.iddentity。

第二行在调用的时候放到了括号中,但是 还是对一个函数的引用,this的值并没有变。这是因为 Object.getImdentity 和 (Object.getImdentity)在规范上是等价的。

第三行执行了一次赋值,然后在调用赋值后的结果,因为赋值表达式的值是函数本身,this的值不再与任何的对象绑定,所以返回的值是 “My Windows”

最后,箭头函数中this 是如何进行查找的呢?

个人是这样理解的:this 向外层作用域中一层层的查找this,直到有this的定义,这个this便是了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值