this指向干货

一:全局中执行

    浏览器环境————————window

    node————————global

sdsd


二:严格模式 ‘use strict’

    'use strict';

    function test() {

        console.log(this);

    }

    test()//undefined

等同于====

(function (){

"use strict";

 console.log(this);

})();


二:作为对象方式调用

第一种情况 作为对象方式调用且  执行

var obj={

    name:"111",

    show:function(){

        console.log(this,this.name)

    }

}

obj.show()//obj,111

等同于=====

function show(){

    console.log(this,this.name)

}

var obj={

    name:"11",

    show:show

}

obj.show()

第二种情况 作为对象方式调用且  没有执行

    var name="quanju"       

  var obj={

              name:"jubu",

              test:function(){

                console.log(this,this.name)           

            }

        }

        var test=obj.test;//虽然引用了obj对象中的函数 ,但是没有执行,

            相当于是吧这个函数引用地址给了变量test,再执行test的时候,是相当于window.test();

          test()//window,'quanju'

   

   

三:作为一个构造函数使用(new)

    function Person(name){

          this.name=name;

            console.log(this)

    }

    var person =new Person("冯思颖");//this指向person,new之后被引用的变量


  四:箭头函数的this 

    简单来说, 箭头函数中的 this 只和定义它时候的作用域(外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window)的 this 有关而与在哪里以及如何调用它无关,同时它的 this 指向是不可改变的,包括 (call, apply, bind) 等操作都无法改变它的 this。

箭头函数没有⾃⼰的this,需要看其外层的是否有函数,

var obj={

  foo1:function(){

        console.log(this)

      },

    foo2:() => {

      console.log(this)

  },

      foo3:function(){

          (()=>{console.log(this)})()

      }

}

obj.foo1()//obj

obj.foo2()//window

obj.foo3()//obj,在foo3内部的箭头函数定义时,它的this就指向了foo3的this。


四:call, apply, bind重定向this

      call传入的参数是call(this对象,参数1,参数2);立即执行

      apply(this对象,[参数1,参数2,参数3]),立即执行

    bind绑定的返回的是一个新的函数,不会立即执行,bind的优先级比call和apply都要高

var obj={

    name:"11",

    age:0,

}

var obj2={

    name2:"222",

    age:0,

    test:function(age){

              this.age=age

    console.log(this,age)   

    }

}

obj2.test(23)//obj2,25

obj2.test.call(obj,"25")//obj,25

obj2.test.apply(obj,[25])//obj,25

var bindObj=obj2.test.bind(obj,25)

bindObj();//obj,25

var  newTest=new  obj2.test.bind(obj,25)//this没有改变,但是能接收到25这个参数

这里使用call和apply会报错,因为new obj2.test.call(obj.25)这里的call的优先级跟一般函数一样,这里的执行顺序会按照点函数从左到右执行,就会变成obj2.test.call。这里的obj2.test.call

并不是一个函数,就会报错。

使用bind时,bind的优先级会高于new,就会先执行obj2.test.bind(obj,25),再执行new。但是这里的this并没有改变。

结论:在 new 这个构造函数的时候,bind 函数所指定的 this 并不会生效;



采坑点:遇到定时器时的this指向

第一种情况:定时器传入的函数是一般的函数时

    var name="quanju"       

  var obj={

              name:"jubu",

              foo:function(){

                console.log(this,this.name)           

            },

foo1:function(){

    console.log(this)//obj

    setTimeout(this.foo, 1000);

}

        }

        obj.foo1();//foo的输出是window,foo1输出的是obj。

     

    坑1:在调用obj.foo1中的setTimeout(this.foo, 1000)中,这里的this.foo也是直接

          拿到的是 foo函数的引用地址,并没有执行,相当于这里放传入的只是一个普通的函数。

    坑2:setTimeout的特性是,即使在严格模式下,setTimeout 方法在调用传入函数的时候,

            如果这个函数没有指定了的 this,那么它会做一个隐式的操作—-自动地注入全局上下文,

            等同于调用 foo.apply(window)。也就是说ding 

  解决:重定向this,在setTimeout调用时外面用var _this=this;在定时器内部使用_this;

第二种情况:定时器传入的函数是一般的函数时

      var obj={

        name:"jubu",

        foo:function(){

                console.log(this,this.name)           

            },

foo1:function(){

    console.log(this)//obj

    setTimeout(()=>{

        console.log(this)//这里的this等同于foo1的this

    }, 1000);

}

}

obj.foo()//obj,jubu

obj.foo1()//obj

       

   

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 先了解 一个基本概念:普通函数的 this 指向不是在定义的时候确定,而是在调用的时候确定。 两个注意事项: 所有...
    Super超_fee3阅读 239评论 0 0
  • this是JavaScript中的一个关键字,但是又一个相对比较特别的关键字,不像function、var、for...
    WEB前端含光阅读 714评论 0 0
  • 葡萄藤PPT JS中this的指向 大家好,我是IT修真院郑州分院第6期的学员王栋,一枚正直、纯洁、善良的前端程序...
    17064阅读 633评论 0 2
  • JS中this的指向 大家好,我是IT修真院郑州分院第6期的学员王栋,一枚正直、纯洁、善良的前端程序员今天给大家分...
    mixable阅读 168评论 0 0
  • 1、es5和es6的区别,说一下你所知道的es6 ECMAScript5,即ES5,是ECMAScript的第五次...
    没糖_cristalle阅读 713评论 0 0