JS中this的使用

JS中的执行上下文「EC」:供代码执行的环境,进栈执行,执行完可能释放也可能不释放

  • 全局执行上下文 EC(G)
  • 块级私有上下文:除函数/对象之外的大括号中,但凡出现基于let/const/function声明变量的,都会产生块级上下文
  • 函数私有上下文:函数执行产生的

THIS:执行主体,谁把它执行的「THIS是谁,和函数在哪创建以及在哪执行都没有半毛钱的关系」

  • 全局执行上下文中的THIS是:window
  • 块级私有上下文中的THIS是:它没有THIS,用到的THIS都是所处环境中的THIS
  • 我们都是研究函数私有上下文中的THIS是谁

JS函数中,THIS可能出现的五种情况:

  • 给当前元素的某个事件行为绑定方法,当事件行为触发,绑定的方法会执行,此时函数中的THIS是当前操作元素本身!
    box.οnclick=function(){
    //点击box后:this->box
    };

  • 方法执行,看方法名前面是否有“点”;有“点”,“点”前面是谁THIS就是谁;没有“点”,THIS是window/undefined;
    // Array.prototype.slice 想把这个slice方法执行?
    let arr=[];
    arr.slice(); //arr基于原型链机制,找到数组原型上的slice方法执行 slice中的this->arr
    arr.proto.slice(); //slice中的this->arr.proto / Array.prototype
    Array.prototype.slice(); //slice中的this->Array.prototype
    const slice=Array.prototype.slice;
    slice(); //slice中的this->window/undefined

    const slice=Array.prototype.slice;
    let arr=[10,20,30,40];
    arr.slice(2); //->[30,40] 找到slice把其执行,方法中的this是arr,所以查找的是arr中索引2及后内容
    slice.call(arr,2); //->[30,40]

    arguments函数的实参集合「类数组,不是Array的实例」
    arguments.slice(0); //报错:arguments.slice is not a function
    slice.call(arguments,0); //这样就好了:把数组原型上的slice执行,让其this变为arguments,实现类数组借用数组的方法,以此达到类数组转换为数组的效果

    匿名函数中THIS的分析

    • 自执行函数
      (function(){
      //this:window/undefined
      })();
    • 回调函数:一般this都是window,除非特殊处理了
      const func=function(callback){
      callback();
      };
      func(function(){
      //this:window/undefined
      });

      const func=function(callback){
      callback.call(obj); //特殊处理
      };
      func(function(){
      //this:obj
      });

      let arr=[10,20,30];
      arr.forEach(function(item,index){
      // 执行数组原型上的forEach: this->arr callback->传递的回调函数 迭代数组中的每一项,每迭代一次就把回调函数执行一次
      // item:当前迭代这一项
      // index:当前迭代这一项的索引
      // 回调函数中的this->window
      });
      arr.forEach(function(item,index){
      // this->obj
      },obj); //forEach中传递的第二个参数,就是改变回调函数中this指向的
  • 构造函数执行「new 执行」,构造函数体中的this是当前实例本身
    function Fn(x,y){
    let num=10;
    this.x=x;
    this.y=y;
    }
    Fn.prototype.sum=function sum(){
    console.log(this.x+this.y);
    };
    let res1=Fn(10,20);
    let res2=new Fn(10,20);

  • 箭头函数中没有自己的THIS,所用到的THIS都是其所处上下文中的THIS
    let obj={
    name:‘刘兴华’,
    age:18,
    fn(){
    //this->obj

        let self=this;
        setTimeout(function(){
            //this->window
            //console.log(this.name);
            console.log(self.name);
        },1000);
    
        setTimeout(()=>{
            console.log(this.name); //obj.name
        },1000);
    }
    

    };
    obj.fn();

  • 基于call/apply/bind可以强制改变THIS指向
    obj.fn(); //fn中的this->obj
    obj.fn.call(arr); //fn中的this->arr

    Function.prototype.call/apply/bind 所有函数都可以调用这三个方法

    • call/apply是把函数立即执行,并且改变其中的this指向
    • bind是预处理的思想,只是预先改变函数中的this,但是此时函数不执行…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

师法智燃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值