最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • What about 'this'?JS中this的用法总结

    正文概述 掘金(进击的Oliver)   2021-02-01   535

    What about 'this'?JS中this的用法总结

    About "this"

    P1:如何使用this?

    • this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。
      这话说起来容易,理解起来缺常常出现问题。请看如下几段代码
      var a =1;
      var obj = {
          a : 0,
          say: function(){ console.log(this.a) }
      }
      var fun = obj.say;
      obj.say(); // 0
      fun();     // 1
      
    • 为什么会出现在这种情况?
      明明我的fun和obj.say指向了同一个函数,而且都在window对象中调用,为什么出现了不同的结果?

    本质上是这样的:

         obj.say()  //等价于 obj.say.call(obj); 你不写.call(obj),浏览器自动帮你写
         fun() 等价于 fun.call(window) 
    
    1. obj当作this传入了say函数中,自然输出的是obj内的a
    2. window对象中执行fun(),就相当于把window当作this传入了该函数中,输出的就是window里的a
    • 更加普遍化的,this其实时时刻刻都伴随着我们的代码
      • 你调用fun(),实际上是执行了fun.call(undefined)
      • 你调用obj.fun(),实际上执行了obj.fun.call(obj)

    如果你传的是null 或者 undefined,那么默认将window传入(严格模式下默认是 undefined) 至此我们基本讲述了this的基本用法

    P2:我们如何判断this指向?

    • 如果要判断一个运行中函数的 this 绑定,就需要找到这个函数的直接调用位置。找到之后就可以按优先顺序应用下面这四条规则来判断 this 的绑定对象。
      1. 由 new 调用,则绑定到新创建的对象。
      2. 由 call 或者 apply (或者 bind )调用?绑定到指定的对象。
      3. 由上下文对象调用?绑定到那个上下文对象。
      function say(){ console.log(this.name) }
      let person = { name:'Jam', age: 18, say: say}
      person.say() // 'Jam'
      
      1. 默认:在严格模式下绑定到 undefined ,否则绑定到全局对象。

    P3:箭头函数中的this

    • 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,箭头函数中没有自己的this的(箭头函数无法使用call,apply),而箭头函数会默认使用父级的this。

    我不知道其他人怎样理解,但如此的定义确实让我难以理解。何为定义时所在的对象?如何使用父级的this?接下来我用实例带你理解。

    let obj = {
    	prin: function(){
            //父级作用域 此处保存着父级的this
    	    setTimeout(()=>{
    	        console.log(this.num);
            },1000)
        }
    }
    let obj1 = { num:1 };
    let obj2 = { num:2 };
    
    1. 首先我们直接执行prin方法试一下

      obj.prin(); // undefined
      

      分析: obj.prin()等价于obj.prin.call(obj), 我们将obj作为this,传到prin函数中此时箭头函数向上查找父级作用域中保存的this, 顺理成章的找到了obj,于是去obj的环境内部寻找num 遗憾的是obj内部并没有num属性,故打印undefined

    2. 尝试改变父级中this的指向

      obj.prin.call(obj1); // 1
      obj.prin.call(obj2); // 2
      

      分析: 父级中的this被赋值为obj1,箭头函数顺着obj1寻找,找到了num属性,打印了它的值 同理父级中的this被赋值为obj2,箭头函数顺着obj2寻找,找到了num属性,打印了它的值

    3. 那我们不如直接给obj一个num属性试试?

      obj.num = 0;
      obj.prin(); // 0
      

      分析: 当obj中拥有了属性num,那么箭头函数一找就找到了它!

    4. 我们再来最后一个例子加深理解!当我把prin函数也用箭头函数书写呢?

      var num = 10,
      //“祖级作用域” window
      var obj = {
          num : 5;
          prin: ()=>{
              //父级作用域 此处保存着父级的this
              setTimeout(()=>{
                  console.log(this.num);
              },1000)
          }
      }
      obj.prin()
      

      你猜猜会输出什么呢? · · · 答案是10!

      分析: setTimeout中的箭头函数到父级作用域中寻找this,发现父级作用域也是箭头函数,于是再向外查 找,找到了“祖级作用域”window,恰好window有num属性,于是setTimeout中的箭头函数快乐地把 window.num打印了出来!

    P4:其他一些总结

    1. 使用let,const声明的变量可能会不符合上述结论。 原因是:let,const 在全局作用域下声明的变量并不会像 var 一样,被添加为window的属性,所以即使在全局中声明了let number = 1, 箭头函数等等也不会在全局作用域中找到 number!
    2. What about 'this'?JS中this的用法总结

    本文借鉴了 @方应杭 老师的思想 zhuanlan.zhihu.com/p/23804247


    起源地下载网 » What about 'this'?JS中this的用法总结

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元