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

    正文概述 掘金(千泷_)   2020-11-24   489

    this

    JS中的this究竟是什么呢?指向什么呢? JS中的this的绑定和函数声明位置没有任何关系,只取决于函数调用的方式,即this指向最后调用他的对象

    既不指向自身也不指向作用域,仅指向调用的对象

    JS如何绑定this指向

    默认绑定
    function fn2(){
        console.log(this) // window
    }
    
    function fn3(){
    	fn2() 
        console.log(this) // window
    }
    fn3()
    

    即独立函数调用, fn3()函数调用本质上是window.fn3() ,fn2()虽然是在fn3函数体内调用但是调用本质也是window.fn2(),所以log出2个window

    隐式绑定

    本质上都是看调用方式来确定this,this就指向最后调用他的对象

    如下几个代码实例

    1

    function fn1(){
        console.log(this.name) // qianlon
    }
    var obj={
        var name ='qianlon'
        fn1: fn1 // 本质上obj中的fn1只是真实fn1函数的一个引用
    }
    obj.fn1() // 
    

    因为调用fn1()的方式为obj.fn1(),所以fn1中的this即指向obj对象

    2

     function fn1() {
       console.log(this.name) // qianlon----1
     }
     var obj1 = {
       name: 'qianlon----1',
       fn1: fn1
     }
      var obj2 = {
       name: 'qianlon----2',
       obj1: obj1
     }
     obj2.obj1.fn1() 
    

    obj2调用obj1,obj1再调用fn1(),所以fn1()的this指向obj1

    3

    易混肴的回调函数(函数作为参数)

    function fn1(){
        console.log(this.name) // qianlon----global
    }
    
    function fn2(fn){
        var name ='qianlon----2'
        fn()
    }
    var name = 'qianlon----global'
    fn2(fn1)
    

    将fn1作为实参传递给fn,fn也就是fn1的引用,fn()调用方法本质上就是window.fn()即window.fn1(),所以this指向window

    JS的内置函数中的回调函数也是如此

    function fn1(){
        console.log(this.name)
    }
    setTimeout(fn1,delay)
    // 内部如下
    setTimeout(fn1,delay){
         // 等待delay/ms
        fn1()
    }
    var name ='qianlon----global'
    

    如何手动绑定this

    call

    fun.call(thisArg, arg1, arg2, ...)thisArg为需要绑定的对象,arg1,arg2为参数列表

    function fn1(){
        console.log(this.name) // qianlon----obj
    }
    var obj={
        name: 'qianlon----obj'
    }
    var name ='qianlon----global'
    fn1.call(obj) 
    

    通过call让fn1中的this指向obj

    apply

    fun.apply(thisArg, arg1, arg2, ...)thisArg为需要绑定的对象,arg1,arg2为参数列表

    function fn1(){
        console.log(this.name) // qianlon----obj
    }
    var obj={
        name: 'qianlon----obj'
    }
    var name ='qianlon----global'
    fn1.apply(obj) 
    
    call apply应用

    实现返回一个手动绑定this指向的指定函数

    // return 一个手动绑定this指向的指定函数
    function bind(fn,obj){
        return function(){
            return fn.apply(obj,arguments)
        }
    }
    
    // 字符串拼接
    function fn1(something) {
      return something + this.name
    }
    var name = '----global'
    var obj = {
      name: '----obj'
    }
    var newFn = bind(fn1, obj) // 获取到指定this的fn1的新函数
    var str = newFn('qianlong')
    console.log(str);// qianlon----obj
    
    new
    • 创建(构造)一个全新对象
    • 该对象会执行[[proptype]]连接
    • 该对象会绑定到函数调用的this
    • 如果函数没有返回其他对象,那么new表达式会自动返回这个新对象

    逐步分析以下代码

     function fn(a){
         this.a =a
     }
    var bar =new fn(2)
    console.log(bar.a)
    
    • new fn(2) 创建了一个全新的对象假设为obj
    • 执行[[proptype]]连接
    • obj就绑定到fn函数中的this,即fn函数中的this就指向obj
    • 由于fn函数没有return一个对象,那么默认就return这个新对象即obj
    • 将obj赋值给bar,即bar为obj的引用
    this绑定的优先级

    这里直接给出结论

    new绑定 > 手动绑定 > 隐式绑定 > 默认绑定

    注意: new绑定内部实现是用手动绑定(call,apply)实现

    思考下一代码

    function foo(something){
        this.a =something
    }
    var obj ={}
    
    var bar =foo.bind(obj) // bind为JS提供的内置手动绑定函数,返回一个经过手动绑定的新函数
    bar(2)
    console.log(obj.a) // 2
    
    var baz =new bar(3)
    console.log(obj.a) // 2
    console.log(baz.a) // 3
    
    • bar是foo函数通过手动绑定到obj的新函数,即bar函数中的this指向obj
    • 所以当执行bar(2)时,obj.a就被修改为2
    • 第十行中,new创建了一个新对象,由于new优先级高于手动绑定,所以此时bar函数的this也就指向新对象
    • 新对象的a就等于3,并且这个对象赋值给baz

    箭头函数

    箭头函数的this等于他上一层作用域的this,如果上一层作用域没有this,那么继续向上层寻找直到找到.

    注意: this无法改变(手动绑定也不可以)

    var name ='qianlon'
    function fn1(){
    	setTimeout(()=>{
            console.log(this.name) // qianlon
        })
    }
    fn1()
    

    因为fn1()的调用方式是window.fn1(),所以fn1函数中的this就绑定window,而箭头函数中的this就等于他外一层函数的this就等于window


    起源地下载网 » JS深入理解this

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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