zoukankan      html  css  js  c++  java
  • 轻松几句搞定【Javascript中的this指向】问题

    this关键字在JavaScript中扮演了至关重要的角色,每次它的出现都伴随着它的指向问题,这也是很多初学者容易出错的地方。

    不过,这篇文章将会带你一次性搞定this指向的问题,望能给大家提供帮助!


    一、谁最终调用函数,this就指向谁!


    这句话是需要牢记的口诀,将this的指向问题转换为分析确定函数最终调用者的问题,以下是对这句话的解释和补充:

                ① this指向谁,不应该考虑函数在哪里里声明的,而是应该考虑函数在哪调用;
                ② this指向的永远是对象,而不可能是函数。
                ③ this指向的对象叫做函数的上下文(context),也叫函数的调用者。

    那么问题又来了,函数的最终调用者如何确定呢?我们先来看一个面试题:

    阅读如下代码,输入的结果应该是?
    var length = 10
    function fn() {
        alert(this.length)
    }
    var obj = {
        length: 5,
        method: function(fn) {
            fn()   // ?  
            arguments[0]()   // ?  
        }
    }
    obj.method(fn);

    试着确定一下,题干中函数的最终调用者是谁?有了答案的话我们继续往下看:


    ★★★   二、this指向的规律    :(跟函数的调用方式息息相关!)


               ① 通过 【 函数名() 】 调用的,this永远指向window;
                ② 通过 【 对象.方法 】调用的,this永远指向对象。obj.func();
                ③ 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr。
                ④ 函数作为window内置函数的回调函数使用,this指向window;
                      setTimeout() setInterval()等
                ⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象。

    针对以上的规律我们分别举例说明:

    ① 通过 函数名() 】 调用的,this永远指向window;

        function func () {
                    console.log(this);
                }
                func();//函数名+()调用,this指向window
                

      ② 通过 【 对象.方法 】调用的,this永远指向对象。

        var obj = {
                    name:"wq";
                    func:func;
                }
                obj.func();//通过对象.方法调用的,this永远指向对象。
        Window.onclick = function  () {
                    document.getElementById("zz").onclick = function  () {
                        func();//函数名+()调用,this指向window
                    }
                    document.getElementById("zz").onclick  = func;//广义对象  通过对象.方法调用的,this永远指向对象
                }
                

    ③ 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr。

      var arr [1,2,3,func,4,5,6]
      arr[3]();//函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,this指向数组arr

    ④ 函数作为window内置函数的回调函数使用,this指向widow;

     setTimeout(func,1000);//函数作为window内置函数的回调函数使用,this指向window;

     ⑤ 函数作为构造函数,使用new关键字调用,this指向新new出的对象。

    var obj1 = new func()//函数作为构造函数,使用new关键字调用,this指向新new出的对象obj1。
      var obj1 ={
                    name:"obj1",
                    arr:[func,1,2,3,4]
                }
     obj1.arr[0]()//最终的调用者是数组。
     setTimeout(obj1.arr[0],2000);//,作为内置函数进行调用,故this指向window;相当于setTimeout(func,2000);

    在结合了相关实例对这几句话进行理解之后,我们再回过头来看一下上面的那道面试题:

    阅读如下代码,输出的结果应该是?
    var length = 10
    function fn() {
        alert(this.length)
    }
    var obj = {
        length: 5,
        method: function(fn) {
            fn()   // ?   10
            arguments[0]()   // ?   1
        }
    }
    obj.method(fn);
    
    答案:fn() // 10  通过函数名()调用,this指向window,即全局变量length。
    arguments[0]() // 1 函数作为数组中的 一个元素,通过数组下标调用的 【  arr[i]() 】,注意此时的数组是arguments,传入实参fn.

    tips:

    在JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。arguments非常类似Array,但实际上又不是一个Array实例。

    arguments对象的长度是由实参个数而不是形参个数决定的。

    最后我们再通过几道面试题来巩固下:

                var fullname = 'John Doe';
                var obj = {
                   fullname: 'Colin Ihrig',
                   prop: {
                      fullname: 'Aurelio De Rosa',
                      getFullname: function() {
                         return this.fullname;
                      }
                   }
                };
                console.log(obj.prop.getFullname()); 
                // 函数的最终调用者 obj.prop 
                
                var test = obj.prop.getFullname;
                console.log(test());  
                // 函数的最终调用者 test()  this-> window
                
                obj.func = obj.prop.getFullname;
                console.log(obj.func()); 
                // 函数最终调用者是obj
                
                var arr = [obj.prop.getFullname,1,2];
                arr.fullname = "JiangHao";
                console.log(arr[0]());
                // 函数最终调用者数组

    如有错误,欢迎大家指正交流!谢谢!

  • 相关阅读:
    KY2成绩排序
    python 获取list中元素的索引
    pandas 读取指定一列数据
    python 删除列表中的第一位元素
    python 时间戳
    python 除法保留小数点后两位
    python 读取excel表格的一列数据并去重
    python中获取Excel表格sheet页整页内容
    IDEA创建spring boot项目
    servlet一些问题
  • 原文地址:https://www.cnblogs.com/wq1994/p/7672565.html
Copyright © 2011-2022 走看看