this指向

一、前言

this关键字是JavaScript中最复杂的机制之一。它是一个很特别的关键字,被自动定义在所有函数的作用域中。对于那些没有投入时间学习this机制的JavaScript开发者来说,this的绑定一直是一件非常令人困惑的事。

在这里插入图片描述


二、了解this

随着函数使用场合的不同,this的值会发生变化。但总有一条原则就是JS中的this代表的是当前行为执行的主体,在JS中主要研究的都是函数中的this,但并不是说只有在函数里才有this,this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用


三、this到底指向谁

1. 函数执行时首先看函数名前是否有“.”

  • 有:"." 前是谁,this就指向谁
  • 无:this均指向window
function fn() {
  console.log(this);
};
//函数无“.”
fn();//this->window

//函数有“.”
let obj = {fn};
obj.fn();//this->obj

//嵌套函数
function fn1() {
  fn();
};
fn1();//this->window

//混合
let f2={
  sum:function() {
  	console.log(this);//this->f2
  	fn();//this->window
  }
}
f2.sum();

在这里插入图片描述

2.自执行函数种的this永远都是window

  (function() {
      console.log(this);
    })();
    
    ~ function() {
      console.log(this);
    }();

~立即执行函数表达式(IIFE)的一种写法,通过~/+/-等运算符将函数体转换成函数表达式,最后加上()就能立即执行

在这里插入图片描述

3. 给元素的某事件绑定方法,当事件触发的时候,this指向的是当前元素

 <button id="btn">按钮</button>
 <script type="text/javascript">
  let onBtn = document.getElementById("btn")
    onBtn.onclick = function() {
      console.log(this);
    }
 </script>

在这里插入图片描述

4.在构造函数模式中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的一个实例

  function fn(name, age) {
      //浏览器默认创建的对象就是我们的实例fn1->this
      this.name = name; //->fn1.name=name
      this.age = age;
      this.writeJs = function() {
        console.log( this.name + this.age);
      };
      //浏览器再把创建的实例默认的进行返回
    }
    var fn1 = new fn("CSDN", 20);
    console.log(fn1.name);//CSDN
    fn1.writeJs();//CSDN20
    
  • 类中某属性值(方法)的this需要看方法执行的时候,前面是否有".",才能知道this是谁;
function Fn() {
   this.x = 100; //this->f1
   this.getX = function() {
   //this->需要看getX执行的时候才知道
     console.log(this.x); 
   }
 }
 var f1 = new Fn();
 f1.getX(); //->方法中的this是f1,所以f1.x=100
 var f2 = f1.getX;
 f2(); //->方法中的this是window ->undefined

5.call、apply、bind

call(fn, n1, …)
  • 第一个参数指定了函数体内this对象的指向;
  • 第二个参数及以后为函数调用的参数
//在非严格模式下
let data={name:"CSDN "};
function fn(num1,num2){
	console.log(num1+num2);
	console.log(this);
}
fn.call(100,200);//this->100 num1=200 num2=undefined
fn.call(data,100,200);//this->obj num1=100 num2=200
fn.call();//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window

//严格模式下 
fn.call();//在严格模式下this->undefined
fn.call(null);// 在严格模式 下this->null
fn.call(undefined);//在严格模式下this->undefined
apply(fn, arr)
  • apply和call方法的作用是一模一样的,都是用来改变方法的this关键字并且把方法执行,而且在严格模式下和非严格模式下对于第一个参数是null/undefined这种情况的规律也是一样的。
  • 区别:call第二个参数开始接受一个参数列表,apply第二个参数开始接受一个参数数组
fn.call(param,100,200);
fn.apply(param,[100,200]);
bind(fn, n1, …)
  • 事先把fn的this改变为我们想要的结果,并且把对应的参数值也准备好,以后要用到了,直接的执行即可;
 var a = {
   name: "Cherry",
   fn: function(a, b) {
     console.log(a + b)
   }
 }
 var b = a.fn.bind(a, 1, 2);
 b();

call、apply、bind优先级要高于其他四种


四、箭头函数this的指向

  • 箭头函数没有自身的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this;
  • 换句话说,箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。
<button id="btn1">btn1</button>
<button id="btn2">btn2</button>
<script type="text/javascript">   
	let btn1 = document.querySelector("#btn1");
	let data = {
	  name: 'GGG',
	  age: 3,
	  getName: function() {
	    btn1.onclick = () => {
	      console.log(this);
	    }
	  }
	}
	data.getName();
 </script>
1. 箭头函数外层存在函数
  • 由于箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
    在这里插入图片描述
2.箭头函数外层不存在函数
  • 虽然存在两个箭头函数,其实this取决于最外层的箭头函数,由于data是个对象而非函数,所以this指向为Window对象
 let btn2 = document.querySelector("#btn2");
 let data2 = {
   name: 'xxx',
   age: 3,
   getName: () => {
     btn2.onclick = () => {
       console.log(this);
     }
   }
 }
 data2.getName();

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值