学习总结:JavaScript之this作用域

学习总结:JavaScript之this作用域

前言

之前一直对js的this作用域处于一个懵懵懂懂的状态,找了个机会看了一些视频跟其他大佬的文章系统的了解补充了一下this作用域知识,然后做了一些学习总结,也是第一次写博客,欢迎大佬们交流经验指出不足。

this作用域

1、定义

每一个行为发生的时候,肯定会有一个发生这个行为的主体。这个主体就是this。
this指代的是当前对象,即正在执行这个(包含this)函数的对象。
也就是说,谁调用这个函数,this就指向谁。

往下看例子

2、this的指向问题

上面说到 谁调用这个函数,this就指向谁

被全局对象调用,this指向全局对象(window)

var value = 'aaa'
function lx () {
	let value = 'bbb';
	console.log(this.value);
}

lx(); // aaa
      // 等同于window.lx();被window调用,指向window。

在构造函数中,this指向实例
(ps:构造函数会生成并返回一个新的对象,this就指向那个对象)

function Lx () {
	this.value = 'bbb';
}
let xx = new Lx(); // this指向new lx(),也就是指向xx
console.log(xx.value); // bbb

谁调用这个函数,this就指向谁
下面这个例子就很清晰了,由xx调用,所以this指向xx

var value = 'aaa'
let xx = {
  value: 'bbb',
  print: function () {
	  console.log(this.value);
	}
}
xx.print();// bbb

接下来我们看这个例子

var value = 'aaa'
  var xx = {
    value: 'bbb',
    print: function () {
      console.log(this.value)
    }
  }
  var jj = {
    value: 'ccc',
    zz: {
      value: 'ddd',
      print: function () {
        console.log(this.value);
      }
    }
  }
  xx.print(); // bbb
  window.xx.print(); // bbb
  jj.zz.print(); // ddd

这个时候出现一个问题
为什么window.xx.print();没有指向window
为什么jj.zz.print(); 没有指向jj

总结下来:
1、如果一个函数中有this,并且它没有被上一级的对象调用,那么this指向window
2、如果一个函数中有this,并且它被上一级对象调用,那么this指向上一级对象
3、如果一个函数中有this,并且包含多个对象,即使它被最外层的对象调用,this也仅指向它的上一级对象。这个跟我们前面说的谁调用这个函数,this就指向谁有些许差异,需要再理解消化。

我们再看两个例子

var value = "aaa";
  let xx = {
    value: "bbb",
    print: function () {
    /*
       return function () {
       		console.log(this.value);
       } 
    */
    // 为了方便理解我写成这样
    var jj =  function () {
        console.log(this.value);
      }
      return jj;
    }
  }
  xx.print()(); // aaa

首先,xx.print()是一个函数,执行后返回jj函数,所以xx.print()()等同于jj()等同于window.jj(),所以对象中有2层或以上的方法时,this指向全局对象;

var xx = {
    value: "aaa",
    jj: {
      value: "bbb",
      print: function () {
        console.log(this); //window
      }
    }
  }
  var zz = xx.jj.print;
  zz();

this永远指向最后调用它的对象,函数print赋值给zz的时候并没有执行,所以this不是指向jj,最终执行的时候是由zz()也就是window.zz(),所以this指向全局对象。

将上一个例子加工一下,变成一个立即执行函数

var value = "aaa";
  let xx = {
    value: "bbb",
    print: (function () {
       return function () {
       		console.log(this.value);
       }
    })()
  }
  xx.print(); // bbb

为什么它不像前面那个例子一样指向window呢,作为一个立即执行函数,他已经被调用并且返回函数,这个函数是被xx调用,所以指向了xx。

说说定时器中的this

  setTimeout(function(){
    console.log(this);
  }, 300)

以这个简单的定时器为例,定时器中的函数会放在全局,被window调用,所以定时器中的this指向全局对象

再说说箭头函数

  let xx = {
    value: "aaa",
    print: () => {
    	console.log(this.value);
    }
  }
  xx.print(); // undefind

按照很多书籍跟例子的说法,箭头函数没有this,this会指向当前函数的上一层作用域(定义时所处的作用域),所以上述例子指向的是全局对象。

那么我们把箭头函数放到定时器中

  let xx = {
    value: "aaa",
    print: function () {
      setTimeout(() => {
        console.log(this.value)
      }, 300)
    }
  }
  xx.print(); // aaa

这时候当前函数的上一层作用域是xx,这个this就指向了xx,最简单的判断方法就是当这个箭头函数不存在,那么根据前面的规则,this该指向谁就指向谁。

关于改变this的指向问题找个时间再继续写,学习借鉴了很多大佬的文档跟视频,做的学习总结,欢迎各位大佬交流指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值