轻松几句搞定Javascript中的this指向问题

Posted 化冰之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轻松几句搞定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]());
            // 函数最终调用者数组

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

 









以上是关于轻松几句搞定Javascript中的this指向问题的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中的this指向

JavaScript中的this指向

JavaScript中的this指向

轻松了解JS中this的指向

this指向

轻松搞定javascript日期格式化问题