简述JS中this的指向

分享人:刘仁瑞

1.背景介绍

2.知识剖析

3.常见问题

4.解决方案

5.编码实战

6.扩展思考

7.参考文献

8.更多讨论

1.背景介绍

this是什么?它有着什么样的功能?


this是javascript的一个关键字,是函数内部的一个特殊对象(或this引用);this在不同的上下文执行环境中指代不同的对象,所以我们可以用同样的this代码输出不同的结果,从而简化代码。

this的特性:


this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。

2.知识剖析

1. 作为普通函数在全局环境中被调用


在全局环境里面,this 永远指向 window,因此在全局环境里作为普通函数被调用的时候,this 也是指向 window。

                        function a(){
                            var name = "技能树";
                            console.log(this.name); //undefined
                            console.log(this); //window
                        }
                        a();
                        

这里调用了a函数,而a函数的执行环境是全局环境,这里的this也就指向了全局变量window。


在全局环境里面,this 永远指向 window,因此在全局环境里作为普通函数被调用的时候,this 也是指向 window。

2.作为对象的属性被调用


先来个总结:如果函数作为一个对象的属性方法,并且被调用的时候,那么这个属性方法中的this 就指向这个对象,来看代码:

                        var o = {
                            name : "技能树",
                            fn : function(){
                                console.log(this.name);
                            }
                        }
                        o.fn(); //技能树
                    
                        var o = {
                            name : "技能树",
                            fn : function(){
                                console.log(this.name);
                            }
                        }
                        window.o.fn(); //技能树
                    

这里出现的结果与上面相同,因为this指向它的直接上级

稍微复杂一点的情况

                        var o = {
                            a : 10,
                            b : {
                                a : 12,
                                fn : function(){
                                    console.log(this.a);
                                }
                            }
                        }
                        o.b.fn(); //12
                    
                        var name = "刘德华"; //window下
                        var person = {
                            name : "梁朝伟",
                            sayName : function(){
                                console.log(this.name);
                            }
                        }
                        var windowSayName = person.sayName;
                        person.sayName(); //梁朝伟,person对象调用,this指向person
                        windowSayName(); //刘德华,window对象调用,this指向widow
                    

但是当在在对象方法中再定义函数,这时候 this 又是 window

                            var name = "刘德华"; //window下
                            var person = {
                                name : "梁朝伟",
                                sayName : function(){
                                    function fn(){
                                        console.log(this); //window
                                        console.log(this.name); //刘德华
                                    }
                                    fn();
                                }
                            }
                            person.sayName();
                        

3.作为构造函数被调用

作为构造函数被调用的时候,this 代表它即将 new 出来的对象;

                        var name = "刘德华";
                        function Person(name){
                            this.name = name;
                            console.log(this);
                        }
                        var person = new Person("梁朝伟");
                        console.log(person.name); //Person {name: "梁朝伟"},梁朝伟
                    

如果不加 new,表示即作为普通函数调用,指向 window。

                            var name = "刘德华";
                            function Person(name){
                                this.name = name;
                                console.log(this);
                            }
                            var person =Person("梁朝伟");
                            console.log(this.name); //window,梁朝伟
                        

因为this指向window,this.name=name,window下的name刘德华被替换为廖朝伟

4作为 call/apply/bind 方法的调用

作为 call/apply/bind 方法被调用的时候指向传入的值。

5.etTimeout、setInterval中的this

6.构造函数 prototype 属性

7.Eval函数

8.箭头函数

3、常见问题



this遇到return怎么办?

4.解决方案


如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。

 虽然null,undefind也是对象,但是在这里this还是指向那个函数的实例,因为null,undefind比较特殊。

                    function fn(){
                        this.user = "技能树";
                        return{};
                    }
                    var a = new fn();
                    console.log(a.user); //undefined
                    
                            function fn(){
                                this.user = "技能树";
                                return function() {};
                            }
                            var a = new fn();
                            console.log(a.user); //undefined
                    
                        function fn(){
                            this.user = "技能树";
                            return 1;
                        }
                        var a = new fn();
                        console.log(a.user); //技能树
                        
                                function fn(){
                                    this.user = "技能树";
                                    return undefined;
                                }
                                var a = new fn();
                                console.log(a.user); //技能树
                        

5、编码实战

6.扩展思考

如何改变this的指向?

可以使用call或者apply的方法

如果xxxx.call(a),this就指向a;当a为null或者undefined的时候,会指向window; 假如说要传参,构造函数名.call("a","b",“c”),它的第一个参数传到的是this;apply类似,但是与之不同的是,要书写成: 构造函数名.apply("a",["b","c"])的形式,这就是差别;

                    // 一个对象可以作为call和apply的第一个参数,并且this会被绑定到这个对象。
                    var obj = {name: 'bob'};

                    // 这个属性是在global对象定义的。
                    var name = 'jac';

                    function foo() {
                      console.log(this.name) // this的值取决于函数的调用方式
                    }

                    foo();          // 'jac'
                    foo.call(obj);  // 'bob'
                    foo.apply(obj); // 'bob'
            

7.参考文献

参考一: 彻底理解js中this的指向

参考二: 慕课网:学会JS的this这一篇就够了,根本不用记

参考三: 知乎:十分钟读懂 JavaScript 中的 this

8、更多讨论

闭包中的this指向的是什么?这个情况过于复杂,有空的深究一下。

鸣谢

感谢大家观看

BY : 刘仁瑞