• JavaScript 中的 this


    非严格模式下, js 中的 this, 在任何时候都能够打印出具体的值。

    其取值的核心规则是:在 es 5 标准下,函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。

    this 的取值,分为四种情况:

    一、构造函数

      构造函数,其实就是 用来 new 对象的函数(首字母大写的那个函数)。例如 Object、Array、Function等。当然,并非所有的函数都要用来作为构造函数。

    function Foo() {
        this.name = 'ADS';
        this.year = 1998;
    
        console.log(this);
    }
    
    var f1 = new Foo();
    
    console.log(f1.name);
    console.log(f1.year);
    
    
    // Foo {name:"ADS",year:1998}
    // ADS
    // 1998

    // 上面代码的打印结果和打印顺序

      以上代码中,如果函数是作为构造函数来使用的话,那么 this 就指向这个即将 new 出来的对象(即 f1)。

      需要注意的是,如果不是按照上面的例子使用 new Foo() ,而是直接调用 Foo() ,this 将指向 Window 对象。

    function Foo() {
        this.name = 'ADS';
        this.year = 1998;
    
        console.log(this);
    }
    
    Foo();
    
    // Window {...}
    

    二、函数作为对象的一个属性

      如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的 this 指向该对象。

    var obj = {
        x: 10,
        fn: function() {
            console.log(this);
            console.log(this.x);
        }
    }
    
    obj.fn();
    
    // object { x:10, fn:() }
    // 10

       注意:

        1.如果 fn 按照 es6 的箭头函数的写法,最终会打印出 Window 对象。

        2.如果 fn 函数不作为 obj 的属性被调用,最终也会打印出 Window 对象。见下例:

    var obj = {
        x: 10,
        fn: function() {
            console.log(this);
            console.log(this.x);
        }
    }
    
    var f1 = obj.fn;
    f1();
    
    // Window {...}
    // undefined
    

    三、函数用 call 或者 apply 调用

      当一个函数被call和apply调用时,this 的值就取传入的对象的值。

      (call 和 apply 两个方法,是每一个函数都包含的、非继承的,作用是在特定的作用域中调用函数,等于设置函数体内 this 的指向,以扩充函数赖以运行的作用域。)

    var obj = {
        x: 10
    }
    
    var fn =  function() {
        console.log(this);
        console.log(this.x);
    }
    
    fn.call(obj);
    
    // object { x: 10 }
    // 10
    

    四、 全局 & 调用普通函数

      1.在全局环境中, this 永远指向 window;

      2.在普通函数调用时,其中的 this 也指向 window。如下例:

    var x = 10;
    var fn = function() {
        console.log(this);
        console.log(this.x);
    }
    fn();
    
    // window { ... }
    // 10
    

       另外,如果在对象内部定义了一个属性,该属性对应一个函数,在这个函数内又定义了一个函数,那么内部的 this 也是指向 Window 的。

    var obj = {
        x: 10,
        fn: function() {
                function f() {
                    console.log(this);
                }
                f();
        }
    }
    
    obj.fn();
    
    // window { ... }
    

    总结: 

      只有在 new Foo() 、作为对象属性直接调用、函数使用 call 或者 apply 时,this 会指向想让其指向的对象,其他情况均指向 Window 对象。

     

    ==================  es 6 箭头函数的 this  ==================

    一、在方法内部,以非方法形式调用

     由于箭头函数不绑定 this, 它会捕获其所在(即定义的位置)上下文中的 this 值,作为自己 的值。

    1.箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this

    2.箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。

    1.所以 call() / apply() / bind() 方法对于箭头函数来说只是传入了参数,对它的 this 毫无影响;

    2.考虑到 this 时语法层面上的,严格模式中与 this 相关的规则都会被忽略;

    例子:

    二、将箭头函数当做一个方法使用

    var obj = {
      i: 10,
      b: () => console.log(this.i, this),
      c: function() {
        console.log( this.i, this)
      }
    }
    obj.b();  // undefined window{...}
    obj.c();  // 10 Object {...}
    

     可以看出来,作为方法的箭头函数this指向全局window对象,而普通函数则指向调用它的对象。

  • 相关阅读:
    centos 更改root密码
    朋友新站http://www.1010yhq.com(1010优惠券网)
    NHibernate从入门到精通系列(3)——第一个NHibernate应用程序
    Windows 进化图
    NHibernate从入门到精通系列(1)——NHibernate概括
    Windows 7最全的硬盘安装方法
    C#面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式)
    NHibernate从入门到精通系列(2)——NHibernate环境与结构体系
    C#面向对象设计模式纵横谈(5):Factory Method 工厂方法模式(创建型模式)
    C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式)
  • 原文地址:https://www.cnblogs.com/cc-freiheit/p/9459496.html
Copyright © 2020-2023  润新知