十分钟彻底理解javascript 的 this指向,不懂请砸店

函数的this指向谁,和函数在哪里被定义的,函数在哪里被执行的没有半毛钱关系,只遵守下面的规律:

在非严格模式中:

1、自执行函数里面,this永远指向window;

    <script>
        var a = 1;
        var o = {
            a: 2,
            fn: (function(){                                //自执行函数,在定义的时候就已经执行啦
                console.log('自执行函数里面是window',this.a);           //自执行函数里面的this指向的是window
                return function() {                                   // 但是这里的this 指向的是谁调用的这个函数
                    console.log('但是还是要具体问题具体分析',this.a)
                }
            })()
        }

        o.fn();
    </script>

结果请看

 2、给元素的某一个行为绑定方法,当行为触发所调用的函数里面this指向的该dom 元素;

    <script>
        var dd = document.getElementById('dd');
        function f1 () {
            console.log(this);
        }
        dd.onclick=f1;       // 点击的那个dom对象
    </script>

但是我要是稍微改一下:

    <script>
        var dd=document.getElementById('dd');
        function fn () {
            console.log(this);
        }
        dd.onclick=function(){
            console.log(this);   // dom 对象
            fn();               // window  ,这时候就看该函数是被谁调用的啦
        }
    </script>

3、看看函数执行有咩有 . ,如果有则是前面的那个,如果没有则是window

4、在构造函数里面,this 指向的是当前的实例;

<script>

       function fn() {
           console.log(this);
       };
       function ff () {
             this.name="杜俊成";   
             this.say=function(){  
                 console.log(this);    // this指向该构造函数的原型
                 fn()                  // window ,因为fn 函数的直接调用者是window,
             }
       }

       var a = new ff();     
       a.say();
    </script>

 5、使用call / apply 改变了this 的指向;(关于call 和 apply 想一劳永逸的搞明白吗?请看我的一篇文章)

严格模式:

 1、自执行函数里面,this永远指向undefined;

    <script>
        var obj ={
            fn:(function(){
                // this => undefined
                console.log(this)
                return function(){
                    // this=> obk
                    console.log(this);
                }
            })()
        }
        obj.fn; //obj.fn 的方法在声明的时候就已经被执行了, window
        obj.fn(); //obj.fn的自执行方法返回的方法执行  obj
    </script>

2、看前面有咩有 . ,如果有则是前面的那个,如果没有则是undefined

总结就是:严格模式和非严格模式的区别:当调用主体不明时,严格模式是undefined,非严格模式是window

<script>
    'use strict';
    function fn(){
        alert(this);
    }
    /*非严格模式*/
    fn.call()//this - window;
    fn.call(null)//this - window;
    fn.call(undefined);//this -undefined
    /*严格模式下,给call或apply第一个参数传谁this就是谁,不传就是undefined*/
    fn.call() //this - undefined;
    fn.call(null) //this -null;
    fn.call(undefined) //this-undefined
</script>
es6 新增的箭头函数比较特殊。我们使用function定义的函数,在定义时,它并不知道这个this会指向哪里,只有在运行的时候才能明确this的值。
 
箭头函数本身不具有this,它会直接绑定到它的词法作用域内的this,也就是定义它时的作用域内的this值。所以试图使用apply,call等方法修改箭头函数的this是不会成功的,因为箭头函数自身没有this。所以我们来看下面一段代码:
var func = () => {
    console.log(this);
}
func(); // Window
func.apply({}); // Window
function func() {
    console.log(this)
    return () => {console.log(this)}
};
func()()
// Window 
// Window
func.apply({a:1})()
// Object {a:1}
// Object {a:1}
func.apply({a:2})()
// Object {a:2}
// Object {a:2}

通过这段代码,我们应该可以明确的看出来,箭头函数是直接使用的它词法作用域内的this,也就是定义它时的作用域内的this。当我们修改它的作用域内的this值,也就是func的this值时,在箭头函数内也可以反映出来。用作对比,我们看下使用function定义的函数:

function func() {
    console.log(this)
    return function(){
        console.log(this)
    }
};
func()()                //window window         
func.apply({a:1})()     // {a:1}  window
func.apply({a:2})()     // {a:2}  window

github地址:https://github.com/dujuncheng

原文地址:https://www.cnblogs.com/dujuncheng/p/6809487.html