This指向

221 阅读4分钟

This指向

1.事件绑定中的this

1.1 行内绑定

 <button id="btn" onclick="clickFun()">点击</button>
 <button id="btn" onclick="console.log(this)">点击1</button>
    // 运行环境在节点中,this指向此节点对象
    <script>
        // 事件绑定
        function clickFun(){
            console.log(this);// 在普通函数中,this指向window
        }
    </script>

直接绑定在行内事件上,this指向绑定的节点对象

创建一个函数,再绑定在行内元素上,this指向window。因为this是在普通函数中,只是被用在行内元素上。

1.2 事件绑定和动态绑定

 <button id="btn" onclick="clickFun()">点击</button>
    <script>
        btn.onclick=function(){
            console.log(this);// 指向调用的对象 button
        }
 // addEventListener事件监听和事件绑定一样,this都指向此节点对象

2.函数内部的this指向

2.1 普通函数 指向window

 function test(){
            console.log(this);// 指向window
        }
        test()

2.2 对象调用 this指向,谁调用就指向谁

 var obj={
            a:1,
            say:function(){
                console.log(this);//  指向Object
            }
        }
        obj.say();//say()被obj调用,所以say()里面的this指向obj
       

2.3 多层嵌套的对象

多层嵌套的对象,内部方法的this指向 离 被调用函数 最近 的对象(window也是对象,其内部对象调用方法的this指向内部对象, 而非window)。

          var o = {
            a: 10,
            b: {
                fn: function () {
                    console.log(this);// 指向b对象
                    console.log(this.a);// undefined 在对象b中,找不到a
                }
            }
        }
        o.b.fn();// 找最近的对象

fn函数b对象近,this指向b对象this.ab对象中没有值,返回了undefined

2.4 对象中函数的赋值

 var obj={
            a:3,
            call:function(){
                console.log(this); //指向window
                console.log(this.a);// undefined
            }
        }
        var f =obj.call;
        f();
        
        
 //可以写成这样
 
 var f=function (){
     console.log(this);
     console.log(this.a);// 函数中找不到a
 }
 f();// 普通函数中,this指向window

为什么会指向window? ? ?

因为函数是对象,对象是按引用传递的

obj.call赋值给f , 相当于把obj.call 的函数赋值给了变量f

也就相当于把obj.call的引用指向了f , 在变量f处调用

fwindow对象的属性 , 所以this指向了window

3. 构造函数的this指向

new关键字改变了函数内this的指向,使其指向刚创建出来的对象

 function Fn() {
        this.user = "追梦子";  // a.user="追梦子
        }
        var a = new Fn();//this指向新创建出来的实例对象a
        console.log(a.user);//追梦子

在构造函数中,当函数中有了return,已经不能称为构造函数了

 function fn() {
            this.user = '追梦子';
            return {}; //undefined
            return function(){}; //undefined
            return 1; // 追梦子
            return undefined; // 追梦子
            return null; // 追梦子
        }
        var a = new fn();
        console.log(a.user);
        
        
        
        /*
        fn的this指向了a,a.user===‘追梦子’;返回值为对象,函数,数组时,改变了this的指向,使其指向return的值,在函数fn中,对象,函数,数组没有user这个属性,返回undefined。
        返回值为基本数据类型时,this指向不改变,仍指向a实例。
        */

new触发函数时,当函数return[] {} function时,this指向return的值

(return的不是引用数据类型时,不改变this的指向,仍指向实例对象)

原型对象中的this

原型对象中this指向new出的实例对象

4. call(),apply(),bind()() 改变this的指向

     `this`指向传入的对象 没有传参,`this`指向`window`

4.1 func.call(obj,参数1,参数2....)

作用1:调用函数

        var obj = {
            name"132"
        }
        
        function fn(){
            console.log(this);
        }
        // 不写参数  只是单纯的调用函数,fn的this依旧指向window
        fn.call();

作用2:改变this的指向

        var obj = {
            name"132"
        }

        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }

        // 将函数fn中的this指向obj对象,类似与obj.fn(),函数也可以传参
        fn.call(obj, 12);

4.2 func.apply(obj,[参数1,参数2...])

作用1:调用函数

    var obj = {
            name: "222"
        }
        
        function fn(){
            console.log(this);
        }
        // 不写参数  只是单纯的调用函数,fn的this依旧指向window
        fn.apply();

作用2:改变this的指向


 var obj = {
            name: "132"
        }

        function fn(arr) {
            console.log(this);
            console.log(arr); //  传入的时候为字符,输出的时候是字符串
        }

        // 将函数fn中的this指向obj对象,类似与obj.fn(),函数也可以传参
        fn.apply(obj, [red]);

4.3 func.bind(obj)(参数1,参数2...)

不会调用原来的函数,可以改变this的指向

改变this的指向


            var obj = {
                age12
            };

            function fn(a,b) {
                console.log(this);
                console.log(a + b);
            }

            // 不能立即调用函数,调用函数时,可以bind()() 调用 或者
            fn.bind();
            // this指向obj  返回的是原函数改变this指向之后的新函数
            var f = fn.bind(obj,1,2);
            f();

使用bind的场景: 不需要立即调用函数,但又想改变函数内部的this指向

按钮点击后,禁用按钮,2秒后开启按钮


        var btn = document.querySelectorAll('button');
        for (var i = 0; i < btn.length; i++) {
            btn[i].onclick = function () {
                this.disabled = true;// 这个this指向btn
                setTimeout(function () {
                
                    // 定时器中的this指向btn  但不立即执行
                    this.disabled = false;

                    // 这里this是定时器外的,指向btn对象,这两种是一样的
                }.bind(this), 2000)
                // }.bind(btn), 2000)

            }

        }

5. 在定时器中

this指向window

            var x=1;
            var o={
                x:2,
                fn:function(){
                    console.log(this.x);
                    console.log(this);
                }
            }
            o.fn();//2 Object
            setTimeout(o.fn,1000);//1 window
// o.fn引用传递

3. 箭头函数

箭头函数中没有this,也没有arguments,主要看写在哪里,找其上下文中的this

在全局中,this===window

函数方法中,主要看函数this的指向,this===function中的this指向

4. 在全局中

this指向window

this===window