函数中的this 和 call,apply和bind的区别

一、函数中的this

1. this是什么?

        任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window

        所有函数内部都有一个变量this,它的值是调用函数的当前对象

2. 如何确定this的值? ==>> 很实用

        test(): window

        p.test(): p

        new test(): 新创建的对象

        p.call(obj): obj

3. 实例

<script type="text/javascript">

  function Person(color) {
    console.log(this)
    this.color = color;
    this.getColor = function () {
      console.log(this)
      return this.color;
    };
    this.setColor = function (color) {
      console.log(this)
      this.color = color;
    };
  }

  Person("red"); //this是谁? window   ==>> 直接调用了构造函数

  var p = new Person("yello"); //this是谁? p   ==>> new了一个Person的实例对象

  p.getColor(); //this是谁? p   ==>> 实例对象调用getColor方法

  var obj = {};
  p.setColor.call(obj, "black"); //this是谁? obj   ==>> 利用call将原本的this指向obj这个空对象

  var test = p.setColor;
  test(); //this是谁? window   ==>> 将 p.setColor 这个方法赋给(引用数据)全局变量test并调用

  function fun1() {
    function fun2() {
      console.log(this);
    }

    fun2(); //this是谁? window  ==>> 函数嵌套(比较常见,还有定时器的回调函数也类似)
  }
  fun1();    // 注意:只有调用fun1,才会触发调用fun2

</script>

 

二、call,apply和bind的区别

相同点:都能指定函数中的this(即改变函数的this)

               都不会改变原函数本身的this。

不同点:

        A. 返回值的不同

              call()/apply()是立即调用函数  ==>> 返回一个改变了 this 后的函数并立即执行,原数组的this不会改变

              bind()是将函数返回(即返回了一个函数对象,需要自己  () 调用)==>> 返回一个改变了 this 后的函数但不会执行,原数组的this不会改变

        B. 传参方式的不同

               call:接受多个参数,第一个是调用函数的对象,后面一次为参数(即参数依次传入,以逗号分隔);如 B.call(A, args1,args2);

               apply:只接受两个参数,第一个是调用函数的对象,第二个是参数且必须是一个数组;如 B.apply(A, arguments)。

               bind:和call很相似,接受多个参数,第一个调用函数的对象,从第二个参数开始是接收的参数列表(即参数依次传入,以逗号分隔);如 B.call(A, args1,args2)。

实例:

<script type="text/javascript">
        let obj = {title: '这是一个新建的Object'};
        function fun(name, age){
          console.log('=====',this)
          console.log('=====name, age',name, age)
        };
        fun('张三', 18)
        console.log('----------111-----------')

        fun.call(obj, '李四', 20);    //this => obj; call传参方式: 依次传入(逗号分隔)
        fun('张三', 18)               //this => Windo; call改变this指向并指向后, 原函数的this是没有变的
        console.log('----------222-----------')

        fun.apply(obj, ['小明', 25]);    //this => obj; apply传参方式: 必须是方式
        fun('张三', 18)                  //this => Windo; apply改变this指向并指向后, 原函数的this是没有变的
        console.log('----------333-----------')

        fun.bind(obj, 'Tom', 30)();    //this => obj; bind传参方式: 依次传入(逗号分隔),必须自己调用
        fun('张三', 18)                //this => Windo; bind改变this指向并指向后, 原函数的this是没有变的

</script>

执行结果:

文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值