this

作者: 马建阳 | 来源:发表于2017-08-12 22:35 被阅读14次

    为何引入this

    为了让函数和对象的属性有一个纽带,并且能自动传第一个参数。具体理解见下图:

    什么是this

    this 就是你call后面的第一个参数 (即call 一个函数时,传入的 context)。

    如何看this表示什么参数

    如果你的函数调用形式不是 call 形式,请按照将其转换为 call 形式。

    JS(ES5)里面有三种函数调用形式:

    1. func(p1, p2) 
    2. obj.child.method(p1, p2)
    3. func.call(context, p1, p2) // 先不讲 apply
    

    第三种调用形式,才是正常调用形式
    其他两种都是语法糖,可以等价地变为 call 形式:

    func(p1, p2) 等价于func.call(undefined, p1, p2)
    obj.child.method(p1, p2) 等价于obj.child.method.call(obj.child, p1, p2)
    

    所以上面三个this分别是window(后面讲),obj.child,context。

    func(p1, p2) 中的 this 如何确定

    function func(){
      console.log(this)
    }
    
    func()
    

    等价于

    function func(){
      console.log(this)
    }
    
    func.call(undefined) // 可以简写为 func.call()
    

    按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:

    如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

    因此上面的打印结果是 window。

    obj.child.method(p1, p2) 的 this 如何确定

    var obj = {
      foo: function(){
        console.log(this)
      }
    }
    obj.foo() 
    

    按照「转换代码」,我们将 obj.foo() 转换为
    obj.foo.call(obj)
    好了,this 就是 obj。搞定。

    具体题目使用

    var obj = {
      foo: function(){
        console.log(this)
      }
    }
    
    var bar = obj.foo
    obj.foo() // 打印出的 this 是 obj
    bar() // 打印出的 this 是 window
    

    请解释最后两行函数的值为什么不一样。
    答案:

    var obj = {
      foo: function(){
        console.log(this)
      }
    }
    
    var bar = obj.foo
    obj.foo() // 转换为 obj.foo.call(obj),this 就是 obj
    bar() 
    // 转换为 bar.call()
    // 由于没有传 context
    // 所以 this 就是 undefined
    // 最后浏览器给你一个默认的 this —— window 对象
    

    相关文章

      网友评论

        本文标题:this

        本文链接:https://www.haomeiwen.com/subject/mczjrxtx.html