美文网首页
JS中this的指向

JS中this的指向

作者: 壹豪 | 来源:发表于2019-08-26 14:37 被阅读0次

    一般涉及到这个问题,大部分的博客都说是谁调用的函数,this就指向谁,但是对于刚入门的人来说还是不太容易理解,像我当时就花了很久。。。可能是因为菜吧。
    下面来讲一下我的理解
    其实谁调用函数this指向谁的确是对的,但是如果基础不够好,是很容易判断错谁调用的函数
    分类写比较好排版,所以分成了大概四类:

    1.一般函数方法调用

    //1.函数声明
    var name = '张三'
    function obj(){
        var a = 'obj'
        console.log(this)//window
        console.log(this.name)//张三
    }
    obj()//window  张三
    window.obj()//window  张三
    

    1.为什么执行了obj()输出的是window?
    因为obj是全局函数,是通过window直接调用的,所以执行obj()其实等同于执行window.obj(),所以其实就是window调用的obj,所以this指向window

    函数表达式其实也是一样的:

    //2.函数表达式
    var name = '张三'
    var obj = function(){
        var a = 'obj'
        console.log(this)//window
        console.log(this.name)//张三
    }
    obj()//window  张三
    window.obj()//window  张三
    

    这是直接调用函数的情况,但是如果函数作为对象的属性去调用就有其他的情况了

    2.作为对象的属性方法调用

    //3.函数作为对象的属性去调用--例一
    var  a='window';
    var obj={
        name:"张三",
        age:"20",
        say:function(){
            var a='obj';
            console.log(this);//就是obj这个对象
            console.log(this.a);//undefined
            console.log(this.name);//张三
        }
    }
    obj.say();//obj{}  undefined  张三
    window.obj.say(); //obj{}  undefined  张三
    

    1.为什么obj.say()中的this.a是undefined呢?
    因为obj.say()中的say()执行的时候是obj直接调用的,因此this指向obj,所以虽然的确是window调用的obj,但是并不是window直接调用的say(),函数的this指向的是直接调用对象,这里是obj

    我们继续看

    //4.函数作为对象的属性去调用--例二
    var  a='window';
    var obj={
        name:"张三",
        age:"20",
        say:function(){
            var a='obj';
            console.log(this);//是obj这个对象
            console.log(this.a);//undefined
            console.log(this.name);//张三
        }
        action:{
            name:"李四",
            age:"25",
            say:function(){
                var a='obj';
                console.log(this);//是action这个对象
                console.log(this.a);//undefined
                console.log(this.name);//李四
            }
        }
    }
    obj.say();//obj{}  undefined  张三
    obj.action.say();//action{} undefined  李四
    window.obj.say(); //obj{}  undefined  张三
    window.obj.action.say();//action{} undefined  李四
    

    1.为什么obj.action.say()执行结果和obj.say()不一样?
    因为obj.action.say()执行say()的时候,其直接调用对象是action而不是obj,所以this指向的是action

    然后我们来看另外一种情况

    //5.函数作为对象的属性去调用--例三
    var  a='window';
    var obj={
        name:"张三",
        age:"20",
        say:function(){
            var a='obj';
            console.log(this);//就是obj这个对象
            console.log(this.a);//undefined
            console.log(this.name);//张三
            function action(){
                console.log(this);//window
                console.log(this.a);//window
                console.log(this.name);//(空)
                console.log(this.age);//undefined
            }
            action();
        }
    }
    obj.say();
    window.obj.say(); 
    

    1.为什么执行action()的时候this指向window?
    因为action()只是在say()函数中进行了普通调用,并不是obj或者say直接调用,所以这时候指向的是全局对象window,
    2.为什么this.name为空而this.age是undefined?
    因为window全局对象本身就有一个默认为空的字段name,所以name是空。
    3.怎么让action指向obj
    在say中用一个变量保存this就然后action()中使用该变量即可。例如在say()函数中var that = this,然后action()函数中把this全部替换为that,就会达到我们想要的效果了。当然还可以使用call或者apply,有关call和apply可以看我的博客

    3.作为构造函数调用

    var name = 'window'
    function obj(){
        this.name = 'obj'
        var age = 20
        console.log(this)//a:obj{}  b:window
        console.log(this.name)//a:obj   b:obj
        console.log(this.age)//undefined
    }
    var a = new obj()
    var b = obj()
    console.log(name)//obj
    

    关于new可看我的博客 —— js new一个函数和直接调用函数的区别

    var name = 'window'
            function obj(){
                var age = 20
                this.name = 'obj';
                console.log(this)
                console.log(this.name)
                console.log(age)
                // this.aa = function(){
                //  return this.name
                // }
            }
            var a = new obj()
            var b = obj()
            console.log(name)
    

    1.a和b声明的时候发什么了什么?
    声明a的时候使用了new,新建了一个对象a,然后obj()中的this指向a,a再链接obj的原型链,再执行obj(),所以a执行时直接调用对象是a
    b其实只是window对象执行了obj()然后将返回值赋给b,如果没有返回值那么b为undefined
    1.为什么b中this.name也是obj呢?
    因为执行obj()的时候this指向的是window,所以在执行this.name='obj'等同于window.name='obj',所以声明b之后输出name也是obj

    4.箭头函数

    箭头函数中根本没有自己的this,因此this指向的是父执行上下文(简单对象(非函数)没有执行上下文)
    有关于执行上下文可看 —— 执行上下文的原理及使用

    5.构造函数

    构造函数可以看js new
    new的时候会新建一个空间并连上构造函数的原型链,再把构造函数的this指向实例,所以调用的属性和方法中的this都是指向实例

    Person(){
     this.name=name
     this.age=age
     this.show=function(){
      console.log(this.name)
      console.log(this.age)
     }
    }
    var a = new Person('张三',20)
    a.name//张三
    a.age//20
    a.show()//张三 20
    

    未完待续

    参考

    相关文章

      网友评论

          本文标题:JS中this的指向

          本文链接:https://www.haomeiwen.com/subject/ihkasctx.html