美文网首页
this全面解析

this全面解析

作者: Ann_l | 来源:发表于2017-10-09 16:25 被阅读0次

    看了《你不知道的js》中this这一章,觉得有必要自己记录总结一下,不然过段时间,可能又忘了。

    每个函数的this是在调用时被绑定的,完全取决与函数的调用位置。
    (1)首先了解一些基础知识:
    什么是调用位置呢?

    函数被调用的位置。

    什么是调用栈?

    到达当前执行位置所调用的所有函数。

    function baz() {
      //当前调用栈是baz,因此当前调用位置是全局作用域
      console.log('baz')
      bar()
    }
    function bar() {
      //当前调用栈是baz-》bar,因此当前调用位置在baz中
      console.log('bar')
      foo()
    }
    function foo() {
      //当前调用栈是baz-》bar-》foo,因此当前调用位置在bar中
      console.log('foo')
    }
    baz()//baz的调用位置
    
    (2)this 的四种绑定规则

    1、默认绑定

    var a = 2;//此时的a就是全局变量,在全局下就能找到a
    function foo() {
      console.log(this.a)//this指向全局对象
    }
    foo()// foo 是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定。
    
    

    2、隐式绑定
    相当于是调用位置有上下文对象,看例子:

    console.log(this)//指向window
    function foo() {
      console.log(this)//{ a: 2, foo: [Function: foo] }
    
      console.log(this.a)//2
    }
    
    var obj = {
      a: 2,
      foo: foo
    }
    obj.foo()//2 调用位置会使用obj上下文来引用函数
    console.log(this.a)//2
    console.log(this)//指向window
    //调用foo时,this被绑定到obj,因此this.a与obj.a 一样
    
    隐式丢失:被隐式绑定的函数会丢失绑定对象
    function foo() {
      console.log(this.a)
    }
    
    var obj = {
      a: 2,
      foo: foo
    }
    var bar = obj.foo//函数别名
    var a = 'hello.dino'
    bar()//bar 引用了foo函数本身,因此此时的bar是一个不带任何修饰的函数调用,因此应用了默认绑定
    值得注意的是:setTimeout和函数别名起到一样的作用
    

    3、显式绑定

    function foo() {
      console.log(this.a)
    }
    
    var obj = {
      a: 2
    }
    foo.call(obj)//相当于强制把obj绑定给foo的this
    call,applay,bind都是用于硬式绑定this的,另外硬绑定的函数,不可能在修改他的this
    如果传入call(null/undefined)硬式绑定会变成默认绑定规则
    

    另外再来一个api调用的上下文

    function foo(el) {
      console.log(el, this.id)
    }
    
    var obj = {
      id: 'awesome'
    }
    var arr = [1, 2, 3]
    arr.forEach(foo, obj)
    /*1 'awesome'
    2 'awesome'
    3 'awesome'*/
    //调用foo时把this绑定到obj,这里的obj就是foreach这类新的内置函数提供的可选参数放置的上下文,作用和bind的一样
    

    4、new绑定

    function foo(a) {
      this.a=a
    }
    var bar=new foo(2)
    console.log(bar.a)
    
    总结一下this规则

    1、函数是否在new中调用?如果是的话,this绑定的是新创建的对象。

    var bar=new foo()
    

    2、是否通过call,apply,bind ,如果是的话,this绑定的是指定的对象。

    var bar=foo.call(obj2)
    

    3、函数是否在某个上下文对象中调用

    var bar=obj1.foo()
    

    4、如果都不是的话,使用默认绑定。指向全局对象。

    var bar=foo()
    

    最后,箭头函数和普通函数有什么区别呢!
    内容太多,,我需要消化一下再来

    相关文章

      网友评论

          本文标题:this全面解析

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