JavaScript中this的指向

概述

      JavaScript在函数内部给我们提供了关键字this,而this是在函数调用的过程中被动态赋值的,JavaScript会将某个对象的地址值存储于this中
      this的指向不是固定的,它会根据当前函数的调用方式的不同而发生变化
      下面我们一起来学习一下this的值会出现的多种情况

一.前置知识

区分构造函数和普通函数
      在JavaScript中,构造函数和普通函数在没被调用前没有任何本质上的区别,唯一的区别只是调用方式的不同
(1)使用关键字new调用的函数,就是构造函数
(2)直接调用的函数,就是普通函数

        function Person(){
            this.name="小明";
            this.age=18;
        }

        //此处使用关键字new调用Person函数,p1中将存储新创建的Person的实例对象的地址值
        //新创建的实例对象身上会有name和age这两个属性
        var p1=new Person();
        console.log(p1.name,p1.age);

        //此处直接调用Person函数,p2中将存储Person函数的返回值(undefined)
        //window身上会有name和age这两个属性
        var p2=Person();
        console.log(window.name,window.age);

二.全局作用域中的this

        //在全局作用域中声明变量num
        var num=1;
        console.log(window.num);//1
        
        //修改this对象身上的num属性,将num属性的值修改为2
        this.num=2;
        console.log(window.num);//2
        console.log(this===window);//true
        //因为在全局作用域中的this指向全局对象window

三.函数内的this的指向

1.对象的方法(隐式调用)

        var p1={
            name:"小明",
            speak:function(){
                console.log("我是"+this.name);
                console.log(this===p1);//true
            }
        }
        
        p1.speak();//调用对象身上的方法时,方法内部的this指向对象本身

2.普通函数(普通调用)

        function Person(){
            this.name="小明";
            console.log(this===window);
        }
        
        Person();//实际上相当于window.Person()
        var p1={
            friend:"小明",
            speak:function(){
                console.log(this===p1);//false
                console.log(this===window);//true
                console.log("我的朋友是"+this.friend);
                //我的朋友是undefined,因为此时this指向window,
                //而window身上并没有friend这个属性,所以读取结果是undefined
            }
        }

        var speak2=p1.speak;
        speak2();//此处相当于window.speak2()

3.构造函数(构造调用)

        function Person(){
            this.name="小明";
            this.age=18;
            this1=this;//将当前函数中的this存储于全局变量this1中,方便外部比较
            return this;//不写效果相同,当使用关键字new调用函数时,函数内部默认会添加上return this;
        }
        var this1;
        var p1=new Person();
        console.log(this1===p1);//true
        //当你使用关键字new调用函数时,函数内部的this指向新创建出来的实例对象,并通过return this返回出来

4.apply/call/bind方法调用(显式调用)

        function Person(){
            this.name="小明";
            this.age=18;
            console.log(this1===this);//apply,call以及bind调用,此处结果都是true
        }
        var this1={
            name:"小红"
        };

        //当将函数作为对象来使用时,使用其身上的apply,call以及bind方法,可以强制改变函数内部this的指向

        //apply/call,立即调用该函数(此处为Person),
        //并将本次函数调用内部的this指向修改为调用apply/call时传入的第一个参数
        Person.apply(this1);
        Person.call(this1);

        //bind,根据该函数(此处为Person),生成新的函数,该函数内部的this将指向调用bind时传入的第一个参数
        var newPerson=Person.bind(this1);
        newPerson();

5.箭头函数(ES6中新增语法)

        function Person(){
            var this1=this;
            var Man=()=>{
                console.log(this1===this);//true
                //箭头函数本身没有属于自己的this,箭头函数的this将指向外层作用域的this
            };
            Man();
        }
        Person();

猜你喜欢

转载自blog.csdn.net/shkstart/article/details/107710331