最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 什么是this?

    正文概述 掘金(敲代码有瘾)   2021-08-04   425

    这是我参与8月更文挑战的第N天,活动详情查看:8月更文挑战

    什么是this?

    通常this的指向分为很多种情况,下面我们一一 来介绍:

    1. 默认情况(默认绑定)

    默认的this

    console.log(this); // window,这里不区分严格模式和非严格模式,都是指向window
    

    在默认情况下,this指向window

    函数中的this

    "use strict";
    function fn(){
        console.log(this);//非严格模式指向window,严格模式指向undefined
    }
    fn();
    
    

    在严格模式下,函数中的this是undefined,但是在非严格模式下,函数中的this指向window

    2. 隐式绑定

    对象方法中的this

    1.如果函数调用是在一个对象上触发的,即存在上下文对象,那么这个函数中的this指向调用函数的对象

    function sayHi(){
        console.log('Hello,', this.name);
    }
    var person = {
        name: 'jack',
        sayHi: sayHi
    }
    var name = 'bob';
    person.sayHi(); // Hello,jack
    

    2.需要注意的是,在对象的属性链中,只有最后一个属性会影响函数中的this。(就近原则)

    function sayHi(){
        console.log('Hello,', this.name);
    }
    var person2 = {
        name: 'jack',
        sayHi: sayHi
    }
    var person1 = {
        name: 'bob',
        friend: person2
    }
    person1.friend.sayHi();// Hello,jack
    

    回调函数中的this

    1.普通回调函数中

    function fn(f){
        f();
    }
    function fn1(){
        console.log(this);
    }
    fn(fn1);
    

    在这个例子中,fn1被作为回调函数调用,回调函数中的this指向和默认绑定的一样,在非严格模式下指向window,在严格模式下指向undefined。

    promise中的.then回调也属于普通回调,同样遵循此规则。

    2.特殊回调函数(定时器回调函数)

    setTimeout(function(){
        console.log(this);
    });
    setInterval(() => {
        console.log(this); 
    },1000);
    

    对于定时器中的回调,不管是在严格模式还是非严格模式下,this稳定指向window。

    3.数组遍历方法中的this

    var arr=[1,2];
    arr.forEach(function(){
        console.log(this);
    })
    

    在数组的遍历方法中,传入的方法其实也是回调函数,如果在这个方法中不指定替代this对象时,同样非严格模式指向window,严格模式指向undefined。

    4.事件回调函数

    document.addEventListener("click",clickhandler);
    function clickhandler(e){
        console.log(this);//侦听事件的对象
    }
    

    在绑定事件的回调函数中,回调函数中的this指向被侦听事件的对象。上面的例子中,this就是document对象。

    5.使用arguments关键字调用回调函数

    function fn(){
        arguments[0]()
    }
    function fn1(){
        console.log(this);//this指向fn中arguments
    }
    fn(fn1);
    

    当在函数中通过arguments调用回调函数时,回调函数中的this指向Arguments对象。

    3.call、apply、bind(显式绑定)

    call、apply、bind都可以通过传递参数来改变this的指向。

    相同点:

    1. 都可以通过传参改变this的指向,传递的第一个参数就是this

    2. 如果第一个参数传null或undefined,那么这些值都会被忽略,this的指向就会走默认绑定规则,非严格模式下指向window

    不同点:

    1. 传参不同:call( this,pra1,pra2,pra3 ),call传递参数是一个一个传递,而apply第二个参数是一个数组 apply( this,[pra1,pra2,pra3] )

    2. call和apply在执行时会直接调用函数,而bind不会调用函数。

    document.onclick = fn.call(obj); // this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined
    document.onclick = fn.bind(obj); // bind会把fn中的this预处理为obj,此时fn没有执行,当点击的时候才会把fn执行
    
    

    4. new 绑定

    在JavaScript中,构造函数只是使用new操作符时被调用的普通函数,不属于某个类,也不会实例化一个类。所有的函数都可以通过new来调用,称为构造函数调用。

    当使用new来调用函数的时候会自动执行以下操作:

        1. 创建一个空对象,构造函数中的this指向这个空对象

        2. 执行原型连接 target.__proto__ = constructor.prototype

        3. 执行构造函数方法,属性和方法都被添加到this指向的对象上

        4. 如果构造函数中没有返回其他的对象,那么就返回this(即创建的这个新对象);否则,返回构造函数中返回的对象。

    function Fn(){
        this.name = 'jack';
    };
    let person = new Fn();
    person.name//jack
    

    上面这个例子中,这个过程就称为构造调用,this将指向新创建的对象person;

    5.箭头函数绑定

    箭头函数是ES6新增的,它和普通函数有一些区别,箭头函数没有自己的this,它的this继承于当前函数执行上下文中的this。

    在使用箭头函数时,有几点需要注意:

        1. 函数中的this,继承的是外层代码块中的this。

        2. 箭头函数不能作为构造函数使用new调用,否则会抛出错误。TypeError: fn is not a constructor

        3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用可以使用rest参数代替。

    // 例1
    let fn = (...vals) => {
        console.log(vals); // [1, 2, 3]
    }
    fn(1, 2, 3);
    // 例2
    let fn = (name, ...vals) => {
        console.log(name); // jack
        console.log(vals); // [1, 2, 3]
    }
    fn('jack', 1, 2, 3);
    

        4. 不可以使用yield命令,所有箭头函数不能用作Generator函数。

        5. 箭头函数没有自己的this,所以不能用call、apply、bind这些方法去改变this的指向。

    总结

    1. 默认绑定

        默认绑定可以理解为函数调用时无任何调用前缀的场景 ,默认绑定的情况下,this指向全局对象window(非严格模式),this指向undefined(严格模式)。

    1. 隐式绑定

        如果函数调用时,前面存在调用它的对象,那么this就会隐式的绑定到这个对象上。如果函数调用前存在多个对象,this指向距离调用自己最近的对象

    1. 显示绑定

        显示绑定就是通过call、apply、bind方法改变this指向。这三个方法传递的第一个参数就是最终的this指向。如果第一个参数是null或undefined,那么this将采用默认绑定的规则,指向全局对象。

    1. new绑定

        使用new绑定时,this指向新创建的那个对象。

    1. 箭头函数

        箭头函数中没有this,箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁。

    例题

    1. 例1
    var obj = {
      a: 10,
      c: 50,
      b: {
        a: 0,
        c: this.a,
        run: function () {
          console.log(this.c);
        }
      }
    }
    obj.b.run();
    
    1. 例2
    var length = 10;
    function fn() {
      console.log(this.length);
    }
    var obj = {
      length: 5,
      method: function (fn) {
        fn();
        arguments[0]();
      }
    }
    obj.method(fn, 1);
    
    1. 例3
    var name = '222';
    var a = {
        name: '111',
        say: function () {
            console.log(this.name)
        }
    }
    var b = {
        name: '333',
        say: function (fn) {
            fn()
        }
    }
    a.say()
    b.say(a.say)
    
    1. 例4
    window.number = 2;
    var obj = {
      'number': 3,
      'db1': (function () {
          console.log(this);
          this.number *= 4;
          return function () {
              console.log(this);
              this.number *= 5;
          }
      })()
    }
    var db1 = obj.db1;
    db1();
    obj.db1();
    console.log(obj.number);
    

    本文参考: 作者:刘小夕 链接:juejin.cn/post/684490…来源:掘金


    起源地下载网 » 什么是this?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元