zoukankan      html  css  js  c++  java
  • 理解JavaScript普通函数以及箭头函数里使用的this

    this

    普通函数的this

    普通函数的this是由动态作用域决定,它总指向于它的直接调用者。具体可以分为以下四项:

    1. this总是指向它的直接调用者, 例如 obj.func() ,那么func()里的this指的是obj。
    2. 在默认情况(非严格模式,未使用 'use strict'),如果函数没有直接调用者,this为window
    3. 在严格模式下,如果函数没有直接调者,this为undefined
    4. 使用call,apply,bind绑定的,this指的是绑定的对象

    箭头函数的this

    箭头函数是没有绑定自己的this,函数内使用的this是由静态作用域(也成为词法作用域,参考this)决定。静态作用域就是说箭头函数里this是由定义它的代码决定,而不是执行调用箭头函数的代码。

    上面的说法有时很难理解,我自己总结的方法是:找出定义箭头函数的上下文(即包含箭头函数最近的函数或者对象),那么上下文所处的父上下文即为this。具体可以参考箭头函数的示例。

    普通函数示例

    示例1:对象函数的this

    var obj = {
      myfunc : function() {
        console.log(this);  
      }
    }
    obj.myfunc();
    

    输出的是obj对象,this指的是obj。

    示例2:全局函数的this

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

    输出的是Window对象,this指的是Window

    示例3:严格模式下全局函数的this

    'use strict';
    function myfunc() {
        console.log(this);
    }
    myfunc();
    

    this为undefined,因为严格模式下,myfunc没有直接的调用者。

    示例1-变形1:在obj.myfunc()方法里添加普通函数,并执行

    var obj = {
      myfunc : function() {
        function innerfunc() {
         console.log(this);
        }
        innerfunc();
      }
    }
    obj.myfunc();
    

    this指的是Window。这是因为innerfunc()函数执行时没有直接调用者,所有this为Window。

    示例1-变形2:把obj.myfunc赋值给一个变量后调用

    var obj = {
      myfunc : function() {
        console.log(this);  
      }
    }
    var f = obj.myfunc;
    f();
    

    this指的是Window。这是因为f()是没有直接调用者,在非严格模式下,this指的是Window。

    箭头函数示例

    示例5:函数内使用箭头函数

    var obj = {
      myfunc : function(){
        var f = ()=>{
          console.log(this);
        }
        f();
      }
    }
    obj.myfunc();
    

    this指的是obj。因为定义箭头函数的上下文为myfunc函数,myfunc函数所在的父上下文为obj。

    示例6:箭头函数作为方法

    var obj = {
      myfunc : ()=>{
        console.log(this);  
      }
    }
    obj.myfunc();
    

    这个地方很容易误以为this指的是obj。其实this实际指的是window,因为定义箭头函数最近的上下文为obj对象(myfunc和箭头函数作为key-value的形式是平级),而obj对象的父上下文为window。

    MDN web docs里说的,建议箭头函数仅用在非方法的函数(non-method function)里。

    示例7:

    var outeobj = {
       outfunc:function() {
         var obj = {
           myfunc : ()=>{
             console.log(this);  
           }
         }
         obj.myfunc();
       }
    }
    
    outeobj.outfunc();
    

    为了和示例6做对比,现在把obj对象添加到outerobj的outfunc里。

    this指的是outobj。这是因为箭头函数最近的上下文为obj对象,而obj对象的父上下文为outobj。

    这是我对this的一点理解以及对箭头函数里使用this的总结,如果有误,敬请指出。

    参考:
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
    https://medium.com/@reasoncode/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4
    http://whatis.techtarget.com/definition/lexical-scoping-static-scoping

    转载于:https://my.oschina.net/jack088/blog/2251580

  • 相关阅读:
    es6类
    ES6模块化
    es6之常/变量
    es6之结构赋值
    es6之箭头函数、rest函数
    es6的新方法
    数组的使用方法
    Vue接口调用问题
    监听器和计算属性
    Vue路由
  • 原文地址:https://www.cnblogs.com/twodog/p/12135749.html
Copyright © 2011-2022 走看看