zoukankan      html  css  js  c++  java
  • 十分钟彻底理解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

  • 相关阅读:
    RWCString 定义 memeroy leak
    打开eclipse报错
    Eclipse 增加php插件
    Shell 字符串的截取
    【转载】Shell判断字符串包含关系的几种方法
    Shell $? $* $@ 等含义
    Shell 获取指定行的内容
    概念性进程
    网络编程
    模块详解
  • 原文地址:https://www.cnblogs.com/dujuncheng/p/6809487.html
Copyright © 2011-2022 走看看