96

JavaScript OOP 之 this指向 - Tracey_W

 6 years ago
source link: http://www.cnblogs.com/Tracey-1023/p/7747372.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JavaScript OOP 之 this指向

今天给大家分享一个JavaScript OOP中关于分辨this指向对象的小技巧,很实用呦!

我们先来看一段代码:

1176772-20171028144623617-562688856.png

大家能判断出func();和obj.func();这两句的this指向吗?

首先,我们都知道的是,this的指向就是最终调用函数的对象。可是最终调用函数的对象,你能清楚地判断出来吗?

但是,有几点需要注意:

  ① this 指向谁,不应该考虑函数在哪声明,而应该考虑函数在哪调用!

  ② this 指向的永远只可能对象,而不可能是函数。

  ③ this 指向的对象 ,叫做函数的上下文context,也叫函数的调用者。 

 什么是上下文context ?    

  经常看到很多资料文档都有提到上下文,但是都不是太好理解。相信很多人犯迷糊。现在尝试把自己的理解写出来,也算是梳理一下。

  上下文 —— 我把它理解为当前运行环境,程序运行时,程序的每条语句都有对应的上下文,即运行环境。

  可以想象一下语句执行前:有个上下文对象,名称是 context,上下文对象是window对象,即: context = window。

  直接调用函数func(),此时函数体内的上下文对象就是window。

  对象obj调用func函数,即:obj.func()  时,函数体内的上下文对象就是window.obj对象。

  this的值,就是运行到this代码位置时,上下文所对应的上下文对象。函数定义是并没有运行console.log(this)语句,所以函数定义是this指向的对象还未定义,它的值是undefined,需要在函数调用时,边解释边执行,执行 console.log(this) 时才分析调用函数是的上下文。最终确定this指向的值。

下面我们来看一下更多的情况,总结一下更多的规律,让大家面对this不再糊涂:

【 接下来,我们详细解读一下 】

① 通过 函数名() 调用的,this永远指向window。就是上述例子的第一个调用 func();

1176772-20171028155529836-698567121.png

结果(window)

1176772-20171028155728883-555708623.png

② 通过 对象.方法 调用的,this指向这个对象。就是上述例子的第二种调用方式 obj.func();

 

1176772-20171028161415398-383938939.png

 结果(obj)

1176772-20171028161451742-285382520.png

③ 函数 作为数组中的一个元素存在,用数组下标调用,this指向这个数组。

1176772-20171028154918430-891350346.png

 结果(数组arr)

1176772-20171028160538648-1873777443.png

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

1176772-20171028160122820-1099522627.png

结果(window)

1176772-20171028155728883-555708623.png

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

 1176772-20171028160832273-1698593768.png

结果(objs)

1176772-20171028161313961-1586175194.png

【区分】在HTML中新增一个div,给div添加点击事件。

<div id="div1" style="width: 200px;height: 200px;background-color: red;" onclick="func(this)">
     这是一个div
</div>

<script type="text/javascript">
        window.onclick = function(){
                 document.getElementById("div1").onclick = function(){  
                 func();   //  最终还是使用()调用,指向Window
            }                            
                 document.getElementById("div1").onclick = func;   // 广义对象  通过对象.方法 调用的,this指向这个对象                
            }          
    function func(){
        console.log(this);
    }
</script>                    
1176772-20171028163703961-1449354410.png

1176772-20171028163731617-787434943.png

规律咱们总结完了,接下来来两个题目练练手吧!

 first one:

function func(){
    console.log(this);
            }
 var obj1 = {
     name : "obj1",
     arr : [func,1,{name:"obj2",func:func},3,setTimeout(func,1000)],
}            // 通过对象取到数组,然后通过数组的下标调用该函数,最终指向数组。this -> obj.arr obj1.arr[0]();                    // obj1.arr[0]:目的是取到func,给setTimeout作为回调函数,相当于setTimeout(func,2000)。this -> window setTimeout(obj1.arr[0],2000); obj1.arr[2].func();    // 最终调用者{name:"obj2",func:func} 属于②情况 setTimeout(obj1.arr[2].func,2000);   // 最终调用者是setTimeout,同上

结果如下显示:(调用了三次延时函数,包括一次自动调用)

1176772-20171028162720851-979064125.png

second one:

    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;  // 给obj追加方法
        console.log(obj.func());     // 函数最终调用者是obj
        
        var arr = [obj.prop.getFullname,1,2];
        arr.fullname = "TraceyW";
        console.log(arr[0]());     // 函数最终调用者数组        
            

结果如下显示:

 

1176772-20171028163105961-496119785.png

总结一下,this指向的规律,大家可以发现,这个规律跟函数的调用方式息息相关:

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

  ② 通过 对象.方法 调用的,this指向这个对象。

  ③ 函数 作为数组中的一个元素存在,用数组下标调用,this指向这个数组。

  ④ 函数作为 Window 内置函数的回调函数使用,this指向window。  如setInterval 、 setTimeout ...

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

挺有用的,拿走不谢!

有需要的点关注呦~~小W会经常更新小技巧呢!如有不完善的地方,敬请拍砖!蟹蟹~~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK