this指向

this是一个指针,指向调用他的对象,它也是一个对象,可以通过this. 调用它的方法,日常用到this主要有这几个方面。

1.全局调用函数 

这里调用test()相当于window.test(),所以这里的this指向window。

        var x = 2;
        function test() {
            console.log(this.x);
        }
        test();    

2.作为对象属性调用

        var o1 = {
            name: 'zhang',
            fn1: function () {
                console.log(this.name);
            }
        }
        o1.fn1();

这里由o1调用fn1(),所以在fn1() 里的this指向调用它的o1,this.name 为zhang。
上面的例子是一层调用,直接对象调用里面的方法,有时候还会有好几层调用。

       var o2 = {
            a: 10,
            b: {
                a: 1,
                fn2: function () {
                    console.log(this.a);
                }
            }
        }
        o2.b.fn2();

有好几层调用,this指向它的上一级调用的this,所以这里输出a为1。

       var o3 = {
            a: 9,
            d: {
                a: 3,
                fn() {
                    console.log(this.a);
                }
            }
        }
        var m = o3.d.fn;
        m();

上面的这个例子,虽然也有好几层调用,但是相当于把fn这个函数赋给m,此时并没有执行,在m()调用才执行,此时调用的环境为 window 所以 this 为window。

        function foo() {
            console.log(this.a)
        }
        var obj = {
            a: 100,
            foo: foo
        }
        var a = 'window global';
        setTimeout(obj.foo, 1000)

此处为obj调用foo,但是并没有执行,而是把foo放进任务队列,在foo执行时环境为window,所以this指向window。

3.构造函数中的this

this指向新创建的对象,当new对象时发生了一下四步:

(1)创建一个新对象

(2)将构造函数的作用域赋给新对象(this指向新对象)

(3)执行构造函数代码为对象添加属性

(4)返回新对象

4.call、apply、bind

call与apply的用法相似,call(obj, arg1, arg2),apply(obj, [arg1, arg2])

        function foo() {
            console.log(this.a)
        }
        var obj = {
            a: 3
        }
        var bar = function () {
            foo.call(obj)   
        }
        bar();
        setTimeout(bar, 1000);

在bar内部手动用call绑定了obj,再用setTimeout也改变不了this指向。

5.箭头函数

普通函数的this指向调用它的对象, 箭头函数的this指向函数定义生效时的对象,准确说箭头函数没有this,它的指向是继承自它的外部代码块,确定了this之后不再被改变。

        function foo() {
            setTimeout(() => {
                console.log('id:', this.id);
            }, 100);
        }
        var id = 21;
        foo.call({ id: 42 });

 

反思:我确实存在这个问题,在讲解问题的时候通常只是通过结论直接来讲解,这样不够细致,希望自己在写博客的时候以及日常开发中注意锻炼这方面的能力

 

posted @ 2019-08-15 00:30  面包树zrp  阅读(129)  评论(0编辑  收藏  举报