【JavaScript函数this指向】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

        this指向问题一直都是一个面试的热点问题那么就让我来学习一下吧。

一、this指向到底是什么?

      this 总是(非严格模式下)指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境;

二、this指向的几种方式

1.默认绑定

代码如下(示例):默认绑定 ,就是独立函数调用。但是要区分严格模式,在严格模式下就是undefined,非严格模式下this指向windo。

独立函数调用我们可以理解成函数有没有被绑定到某个对象上调用。

    非严格模式  this指向  window
    <script>
        function foo() {
            console.log(this);
            // this 指向window
        }

        foo();
    </script>    

    严格模式下  this指向  undefined
    <script>
        // 严格模式    "use strict"
        "use strict"

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

        foo();
    </script>

2.隐式绑定

代码如下(示例):隐式绑定是另一种比较常见的调用方式,就是通过某个对象进行调用。

 也就是说他是通过某个对象发起的函数调用,this指向这个对象

    <script>
        var info = {
            name: "李四",
            bar: function() {
                console.log(this);
            }
        };
        // 这种this指向就是 info
        info.bar();
        // 这种 this指向是 window 因为将函数赋值给fn变量
        // 因为 fn()是一个函数 他是独立调用的 所以this指向window
        var fn = info.bar();
        fn();
        // 总结 函数调用 前面写谁 this就指向谁  如果只是单一的调用那就指向window
    </script>

 3.new绑定  构造函数绑定

  代码如下(示例):JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字。

使用new关键字来调用函数   

  • 创建一个全新对象
  • 这个this就会指向创建的空对象
  • 给这个空对象身上追加属性
  • 函数执行完毕,会自动的将this返回给函数的调用者
  • 函数的调用者就是我们由构造函数创建的实例对象             
 <script>
        // 1.声明函数
        // 4.设置形参  接受实参
        function Person(name, height, weight, addr) {
            // new过程中  做了什么事情
            // 5-1.创建一个全新对象
            // 5-2.这个this就会指向创建的空对象
            // 5-3.给这个空对象身上追加属性
            // 5-4.函数执行完毕,会自动的将this返回给函数的调用者
            // 5-5.函数的调用者就是我们由构造函数创建的实例对象          
            this.name = name;
            this.height = height;
            this.weight = weight;
            this.addr = addr;
            console.log(this);
            console.log(height);
        }
        // 2.函数的调用
        // 3.传入实参
        var p1 = new Person("张三", 1.88, 60, "河南");
        console.log(p1);

4. 显示绑定

代码如下(示例):明确的绑定了this指向的对象,就称为显示绑定

隐式绑定有一个前提

  • 必须在调用的对象内部有一个对函数的引用(比如一个属性);
  • 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
  • 正是通过这个引用,间接的将this绑定到了这个对象上;

call和apply方法的使用

        第一个参数都是相同的 都是表示this的指向 。

        后面的参数  apply为数组 ,call为列表参数

    <script>
        function fn() {
            console.log(this);
        }
        var obj = {
            name: "obj",
        };
        // 函数调用方式
        // this 默认指向window
        fn();
        // apply call 也可以调用函数  还可以改变this指向
        // apply call 如果里面不写参数 那么还是默认指向window
        //   如果添加参数 添加谁this就指向谁
        fn.apply(obj);
        fn.call(obj);
    </script>

apply和call 添加参数 

    <script>
        function fn(name, height, weight, addr) {
            console.log(name, height, weight, addr);
        }
        fn("张三", 1.88, 70, "河南");

        // apply 方法 调用函数
        // 第一个参数 是this指向  
        // 第二个参数 是以一个数组的形式传入   数据传入到数组中
        fn.apply("hello", ["李四", 1.70, 55, "南昌"]);


        // call 方法 调用函数
        // 第一个参数 是this指向
        // 即第一个参数之后的参数依照列表的形式传入实参   将数据依次传入
        fn.call("nihao", "王五", 1.50, 100, "上海")
    </script>

 bind的方法使用 

        bind()方法也可以改变this指向 ,传入实参和call方法相同

         但是这个方法  不会调用函数   只会改变this指向

         他会产生一个新函数  函数被称为   BF

 <script>
        function fn() {
            console.log(this);
        }
        var obj = {
            name: "张三"
        }

        //第三种方法 改变this指向 fn.bind()  传入实参和call用法相同
        // 这个方法 不会调用函数 只会改变this的指向 
        // 并且产生一个新函数   新函数被称为 BF
        var bar = fn.bind(obj, "李四", 188)
        bar()
    </script>

5.内置函数的绑定

代码如下(示例):

  • 这些内置函数会要求我们传入另外一个函数;
  • 我们自己并不会显示的调用这些函数,而且JavaScript内部或者第三方库内部会帮助我们执行;
 <button>点击</button>
    <script>
        // 定制器   this指向window
        setInterval(function() {
            // console.log(this);window
        }, 1000);

        // 点击事件  this指向 button
        var btn = document.querySelector("button");
        btn.onclick = function() {
            console.log(this);
        }

        var obj = {
                name: "海绵宝宝"
            }
            // 高阶函数    高阶函数需要另一个函数作为参数
        var arr = ["张三", "李四", "王五"];
        arr.forEach(function(item, index, addr) {
            // console.log(item, index, addr);
            console.log(this);
        }, obj)
    </script>

 6.箭头函数

代码如下(示例):箭头函数没有this指向  他会向外一层作用域去找   如果上一层没有那就一直向上一层查找一直到全局 要是还没找到那就指向 window

箭头函数有自己的作用域   但是没有this指向

<script>
        // 全局 this
        console.log(this);

        var foo = () => {
            // 箭头函数里面没有this
            // 箭头函数有作用域 如果我们想输出一个变量
            // 自己作用域里面没有 那向上一层作用域中查找
            // 如果上一层没有  那就找到全局作用域
            // 找到全局作用域  this 指向 window
            console.log(this);
        }
        foo();
    </script>

总结

提示:这里对文章进行总结:

  1. 默认绑定 this 指向    严格模式指向undefind ,非严格模式指向window
  2. 隐式绑定 this指向     this指向调用的对象
  3. new绑定 构造函数 this指向    this指向创建的新对象
  4. 显示绑定 this指向       this指向自己传入的对象
  5. 内置函数的绑定 this指向  this指向因情况而定  详情请看上面解释
  6. 箭头函数  this指向      箭头函数没有this指向

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值