js高阶——this指向

this指向调用函数的对象。

this一定指向一个对象。

this的指向一定是一个对象(面向对象:函数一定是被某个对象调用)。

1、全局作用域下,this始终指向window对象。

  console.log(this);//window

2、函数内部的this,在非严格模式下,指向window对象:

    aa()
    function aa() {
      bb();
      console.log(this);//window
      function bb() {
        console.log(this);//window
      }
    }

3、函数内部的this,在严格模式下:

    aa();
    window.aa();

    function aa() {
      'use strict'
      console.log(this);
    }

使用aa()调用时,this是undefined,使用window.aa()调用时,指向window。

4、对象中的this,谁调用就指向谁:

    const obj = {
      fn: function () {
        console.log(this)
      },
      abc: {
        fn: function () {
          console.log(this)
        }
      }
    }
    obj.fn();//obj
    obj.abc.fn();//obj.abc

如果对象b继承对象a:

	const a = {
        fn:function(){
            console.log(this)
        }
    }
    const b = Object.create(a);
	b.fn();//this指向b
	a.fn();//this指向a

5、箭头函数中的this:

        箭头函数中没有this和arguments。 箭头函数的this指向window

    const obj = {
      abc: {
        fn: () => {
          console.log(this)
        }
      }
    }
    obj.abc.fn();
//因为obj在window作用域下,所以箭头函数的this指向window。

6、构造函数中的this:

构造函数在生成对象时,this指向生成的对象实例。没有生成前,函数的this没有确定指向。

	function fn() {
      this.a = 123;
      this.b = function () {
        console.log(this);
      }
    }
    let abc = new fn();
    abc.b();

7、原型链中的this:

指向它调用它的对象,而不是从原型链上找到它时,它所属于的对象。

    const father = {
      a: function () {
        console.log(this)
      }
    }

    const son = { b: 2 };

    Object.setPrototypeOf(son, father)

	father.a()//father
    son.a()//son

call、apply、bind可以改变this的指向。

    const obj = { a: 1 };
    fn(1, 2, 3, 4, 5);
    fn.call(obj, 1, 2, 3, 4, 5);


    function fn(a, b, c, d, e) {
      console.log(this, a, b, c, d, e);
    }
    const obj = { a: 1 };
    fn(1, 2, 3, 4, 5);
    fn.apply(obj, [1, 2, 3, 4, 5]);


    function fn(a, b, c, d, e) {
      console.log(this, a, b, c, d, e);
    }

call要求调用函数时的参数,以传统的方式附加。

apply要求调用函数时的参数,必须以数组的形式传入。

    const obj = { a: 1 };
    fn(1, 2, 3, 4, 5);
    const f = fn.bind(obj);
    f(1, 2, 3, 4, 5)

    function fn(a, b, c, d, e) {
      console.log(this, a, b, c, d, e);
    }

bind方法不会直接调用函数,而是返回一个this指向确定的新函数。

总结:

  1. call 、apply、bind都会改变函数执行时 this的指向。

  2. call、apply是直接执行函数,而 bind是不执行函数,返回新的函数。

  3. call要求其他参数正常传入,apply要求其他参数以数组的形式统一传入。

    const h1 = document.querySelector('h1');
    const h2 = document.querySelector('h2');

    h1.onclick = h1_click.bind(h2);

    function h1_click() {
      this.style.color = 'red';
    }

某些情况下,我们可能会书写一个函数,用来为一系列元素进行操作,但是,开始又不确定是对哪个元素操作,就可以使用this替代。

在调用时,有bind确定this的指向。

 const h1 = document.querySelector('h1');
    const h2 = document.querySelector('h2');

    h1.onclick = h1_click;
    const h2_hide = hide.bind(h2);
    const h1_hide = hide.bind(h1);

    function h1_click() {
      h2_hide();
      h1_hide();
    }

    function hide() {
      const elem = this;
      let o = 1;
      aa();
      function aa() {
        if (o > 0) {
          o -= 0.01;
          elem.style.opacity = o;
          setTimeout(aa, 10);
          // requestAnimationFrame(aa);
        }
      }
    }

在这里,我们设置了hide函数,但执行的主体不确定,因此用this替代。

const h2_hide = hide.bind(h2);
const h1_hide = hide.bind(h1);

将hide函数不确定的this,指向确定的对象,返回新的函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值