zoukankan      html  css  js  c++  java
  • JavaScript中的this的指向

    this是JS的关键字,随着函数使用场合的不同,this值会发生变化。但总的原则是,this总是指向调用this所在函数的那个对象

    1、纯函数调用

    function test(){
    this.x=1;
    alert(x);
    } 
    test();

    这里的this就是全局变量。看下面的例子就能很好的理解this就是全局对象Global。

    var x=1;
    function test(){
       alert(this.x);
    }
    test();  //1
    
    var x=1;
    function test(){
       this.x=0;
    }
    test();
    alert(x);  //0

    在JavaScript的变量作用域中规定,“全局变量都是window对象的属性。”因此执行test()时相当于window.test(),此时test函数体内的this关键字的指向变成了window对象。即将window对象的x变为0。

    var x=1;
    var b={
       x:2,
       getX:function(){
          return this.x;
       }
     };
    alert(this.x);     //1
    alert(b.getX()); //2

    在上面的代码中,alert(this.x)中this指向window,所以在全局中搜寻x的值,为1;

    alert(b.getX())中由于x所在函数作为对象b的方法被调用,this指向了b,因此在b中搜寻x的值,为2。

    2、作为方法调用,那么this指调用方法的这个对象

    function test(){
    alert(this.x);
    }
    var o={};
    o.x=1;
    o.m=test;
    o.m();  //1

    3、作为构造函数调用。此时this指向新生成的对象。

    function Test(){
       this.x=1;
    }
    var o= new Test();
    alert(o.x);  //1

     4、apply调用。this指向的是apply中的第一个参数

    var x=0;
    function test(){
       alert(this.x);
    }   
    var 0={};
    o.x=1;
    o.m=test();
    o.m.apply();  //0
    o.m.apply(o);//1

     当apply没有参数时,表示为全局对象。所以值为0。

    5、箭头函数中的this

    箭头函数要实现类似纯函数的效果,必须剔除外部状态。所以当你定义一个箭头函数时,在普通函数里常见的this、arguments、caller都是没有的。

    箭头函数里没有this。如下代码里可以取到this。这是为什么呢?

    function foo(){
       let a=1;
       let b=()=>console.log(this.a);
       b();
    }
    foo();  //1

    以上箭头函数中的this实际上是父级作用域中的this,即函数foo的this。箭头函数引用了父级的变量,构成一个闭包。以上代码等价于:

    function foo(){
       let a=1;
       let self=this;
       let b=()=>console.log(selt.a);
       b();
    }
    foo();  //1

    箭头函数不仅没有this,常用的arguments也没有。如果你能获取到arguments,那它一定是来自父作用域的。

    function foo(){
       return ()=>console.log(arguments[0]);
    }
    foo(1,2)(3,4);  //1

    上例中如果箭头函数有arguments,就应该输出的是3而不是1。

    一个经常犯的错误是使用箭头函数定义对象的方法,如:

    let a ={
        foo:1,
        bar:()=>console.log(this.foo)
    };
    a.bar();   //undefined

    以上代码中,箭头函数中的this并不是指向a这个对象。对象a并不能构成一个作用域,所以再往上到达全局作用域,this就指向全局作用域。如果我们使用普通函数的定义方法,输出结果就符合预期,这是因为a.bar()函数执行时作用域绑定到了a对象。

    let a ={
        foo:1,
        bar:function(){console.log(this.foo)}
    };
    a.bar();  //1

    另一个错误是在原型上使用箭头函数。如:

    function A(){
        this.foo=1; 
    }
    A.prototype.bar=()=>console.log(this.foo);
    let a=new A;
    a.bar();   //undefined 

    同样,箭头函数中的this不是指向A,而是根据变量查找规则回溯到了全局作用域。同样,使用普通函数就不存在问题。在什么情况下使用箭头函数:

    A、箭头函数适合于无复杂逻辑或者无副作用的纯函数场景下。例如用在map、reduce、filter的回调函数定义中;

    B、不要在最外层定义箭头函数,因为在函数内部操作this会很容易污染全局作用域。最起码在箭头函数外部包一层普通函数,将this控制在可见的范围内;

    C、箭头函数最大的好处是简洁。在有多层函数嵌套的情况下,箭头函数的间接性并没有提升,反而影响了函数的作用范围的识别度,这种情况不建议使用箭头函数。

  • 相关阅读:
    给存储过程传递一个表
    Linker problems with Borland builder
    Python内置函数super的不便之处
    接口测试基础
    接口测试工具篇postman
    接口测试工具篇jmeter
    git的使用
    git与pycharm结合使用
    抓包工具fiddler
    sql 中 case when 语法
  • 原文地址:https://www.cnblogs.com/haidaojiege/p/6971765.html
Copyright © 2011-2022 走看看